2016-12-01 11 views
0

と一致しませんでした:が、これは私の現在のコードで期待されるタイプ(カスタムタイプ)

data Exp x = Con Int | Var x | Sum [Exp x] | Prod [Exp x] 
    | Exp x :- Exp x | Int :* Exp x | Exp x :^ Int 

expression :: Exp String 
expression = Sum [3:*(Var"x":^2), 2:*Var"y", Con 1] 

type Store x = x -> Int 

exp2store :: Exp x -> Store x -> Int 
exp2store (Con i) _  = i 
exp2store (Var x) st = st x 
exp2store (Sum es) st = sum $ map (flip exp2store st) es 
exp2store (Prod es) st = product $ map (flip exp2store st) es 
exp2store (e :- e') st = exp2store e st - exp2store e' st 
exp2store (i :* e) st = i * exp2store e st 
exp2store (e :^ i) st = exp2store e st^i 

経験が多項式とexp2storeを表す必要は値を式の中で変数を提供発現および機能を取ります。

例:作品

*Main> exp2store (Var"x") $ \"x" -> 5 
5 

。異なる値の複数の変数をどのように供給できるかわかりません。つまり、

*Main> exp2store (Sum[Var"x",Var"y"]) $ \"x" "y" -> 5 10 

明らかに、これは例外をスローします。誰か助けてくれますか?

答えて

4

一般的な公式がない場合、任意の入力を出力にマップする無名関数を書くのは難しいです。まず、アソシエーションリストを使用することができます。標準関数lookupは、与えられた変数の値を得ることができます。 (これが最善の実行方法ではありませんが、それはあなたが開始するために、任意の追加輸入を避けることができます。)

-- I lied; one import from the base library 
-- We're going to assume the lookup succeeds; 
import Data.Maybe 

-- A better function would use Maybe Int as the return type, 
-- returning Nothing when the expression contains an undefined variable 
exp2store :: Eq x => Exp x -> [(x,Int)] -> Int 
exp2store (Con i) _  = i 
exp2store (Var x) st = fromJust $ lookup x st 
exp2store (Sum es) st = sum $ map (flip exp2store st) es 
exp2store (Prod es) st = product $ map (flip exp2store st) es 
exp2store (e :- e') st = exp2store e st - exp2store e' st 
exp2store (i :* e) st = i * exp2store e st 
exp2store (e :^ i) st = exp2store e st^i 

定義されているあなたは、あなたをStoreを保つ必要がある場合は

exp2store (Sum[Var"x",Var"y"]) $ [("x",5), ("y",10)] 

として関数を呼び出しますこのようにあなたの電話を書くことができます

exp2store (Sum[Var"x",Var"y"]) $ \x -> case x of "x" -> 5; "y" -> 10 
関連する問題