3

Haskell の一般的な計算を型レベルで表現するための適切な慣用的な方法が存在する必要があります。私が思いつくことができるのは、この(違法な)オブジェクト指向の模倣だけです。

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

理想的には、私は開放性を維持したいので、このアプローチは私には魅力的ではありません. 求めすぎですか?

4

2 に答える 2

3

あなたが持っているアプローチで確かにそれを行うことができます.構文といくつかの詳細を正しくする必要があるだけですが、これは確かに機能します:

class Computation a where
    compute :: a -> Double

instance Computation Double where
    compute = id

data Square a = Square a

instance Computation a => Computation (Square a) where
    compute (Square underlying) = square $ compute underlying where square i = i * i

data Scale a = Scale a Double

instance Computation a => Computation (Scale a) where
    compute (Scale underlying c) = c * compute underlying

data Add a = Add a Double

instance Computation a => Computation (Add a) where
    compute (Add underlying c) = c + compute underlying

test :: Add (Scale (Scale (Square Double)))
test = Add (Scale (Scale (Square 2) 5) 0.5) 100

main :: IO ()
main = print $ compute test

Computationforのインスタンスを追加する必要があったことに注意してください。Doubleこれは単にconst. test式は と同等である必要があり(((2^2) * 5) * 0.5) + 100、実際にこれら 2 つの結果を比較すると、同じ値が得られます。

ただし、これがあなたが望んでいたアプローチであるかどうかは完全にはわかりません。これは、投稿したリンクに示されている方法と実際には同等ではありません.変数を表現することは、このエンコーディングではかなり難しいでしょう.

于 2014-08-12T03:22:23.403 に答える