Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 380
Justin L. Avatar asked Nov 16 '25 12:11

Justin L.


1 Answers

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.

like image 183
dfeuer Avatar answered Nov 19 '25 10:11

dfeuer