2015-06-14 38 views
4

我代表演算哈斯克爾以下代數數據類型:哈斯克爾LAMBDA倍

data LExpr 
    = Var String   -- variable 
    | App LExpr LExpr -- function application 
    | Lam String LExpr -- Lambda abstraction 
    deriving (Eq, Show) 

我試圖建立與之相適應摺疊功能。我與一般的摺疊形式代數數據類型,它可以是這樣的方式存在認識:

foldr :: (α -> β-> β) -> β -> [α] -> β 
foldr (#) z = go 
    where 
    go []  = z 
    go (x:xs) = x # go xs 

所以,我迄今所做的:

lfold :: (String -> a) -> (a -> a -> a) -> (String -> a -> a) -> LExpr -> a --given by definition 
lfold f z = go 
    where 
    go (Var _) = z   --Not sure here how to do the base case 
    go (Lam v e) = v f go e 

這是正確的方法是什麼?如果不是,我錯了,如何解決它?

+0

看看你的簽名,它與'foldr'不同,你應該命名變化的變量。還要記住用圓括號包裝你的構造函數。例如'v f go e'的類型爲'String','String - > a','LExpr - > a'和'LExpr',這是一個無意義的調用鏈。 – Guvante

+0

@Guvante確定那麼對應的簽名是什麼? – user8

+1

http://stackoverflow.com/questions/16426463/what-c​​onstitutes-a-fold-for-types-other-than-list –

回答

1

我只會提供提示。

假設你有一列整數類型,如下所示:

data List = Nil | Cons Int List 

然後,折變成

foldr :: β -> (α -> β -> β) -> [α] -> β 
foldr nil cons = go 
    where 
    go Nil   = nil 
    go (Cons x xs) = cons x (go xs) 

注意的是,一旦我仔細命名參數nil, cons那麼它只是一個事1)將Nil(構造函數)映射到nil(參數),2)將Cons映射到cons,3)將go應用於List類型的子項(即,即,xs)。

你的類型,

data LExpr 
    = Var String   -- variable 
    | App LExpr LExpr -- function application 
    | Lam String LExpr -- Lambda abstraction 

我們可以用同樣的伎倆:

lfold :: (String -> a) -> (a -> a -> a) -> (String -> a -> a) -> LExpr -> a 
lfold var app lam = go 
    where 
    go (Var v)  = ?? 
    go (App e1 e2) = ?? 
    go (Lam v e) = ?? 

注意我是如何命名的三個參數:var, app, lam。通過檢查上述List類型中發生的情況,您現在應該可以填寫空白。

+0

'go(Var v)= v','go(App e1 e2)= go e1 ++ go e2'和'go(Lam ve)= v app go e'?我對嗎?並感謝您的解釋。 – user8

+1

@ user4325010不,回想一下,我們將'Nil'映射到'nil'和'Cons'映射到'cons'。所以'Var'必須映射到...特別是'Var v'必須映射到'... v'。 – chi

+1

'go(Var v)= var v','go(App e1 e2)= app(go e1)(go e2)','go(Lam v e)= lam v(go e)'?對? – user8