There must exist a good idiomatic way to express general computations in Haskell on type level. All I can come up with is this (illegal) OO imitation.
class Computation where
compute :: Computation -> Double -> Double
data Id = Id
instance Computation Id where
compute _ = id
data Square a = Computation a => Square a
instance Computation (Square a) where
compute (Square underlying) x = sqr $ compute underlying x where square x = x*x
data Scale a = Computation a => Scale a Double
compute (Scale underlying c) x = c * compute underlying x
Ideally, I would like to retain openness, so this approach doesn't appeal to me. Am I asking for too much?