Search code examples
haskellpattern-synonyms

Manually specifying ismorphisms for unidirectional pattern synonym


There probably isn't a way to do this, but I just wanted to ask just in case.

I have a data type that's a simple tuple like this:

data Tup a = T a a

I have a pattern synonym like this:

pattern (:?) :: () => Floating a => a -> a -> Tup a
pattern (x :? y) <- T x (sqrt->y)

That matches on T x y, but gives y square rooted. so:

let (_ :? y) = T 1 4 in y

is

2.0

I'd also like to be able to use :? as a constructor, so I'd be able to do cool things like:

1 :? 2

evaluating to

T 1.0 4.0

Of course I'd have to manually specify the isomorphism, but is there any syntax or language feature that would enable me to get this behavior?


Solution

  • As of GHC 7.10, you can use

    pattern (:?) :: () => Floating a => a -> a -> Tup a
    pattern (x :? y) <- T x (sqrt->y) where
      x :? y = T x (y^2)
    

    My main concern is that sqrt and ^2 are not quite inverses, both because negative numbers don't have real square roots and because floating point arithmetic is imprecise.