Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Haskell-Lambda褶皱_String_Haskell_Lambda_Fold_Algebraic Data Types - Fatal编程技术网

String Haskell-Lambda褶皱

String Haskell-Lambda褶皱,string,haskell,lambda,fold,algebraic-data-types,String,Haskell,Lambda,Fold,Algebraic Data Types,我有以下表示Haskell中Lambda演算的代数数据类型: data LExpr = Var String -- variable | App LExpr LExpr -- function application | Lam String LExpr -- Lambda abstraction deriving (Eq, Show) 我正在尝试构建附带的fold函数。我熟悉代数数据类型的一般折叠形式,它可以以这种方式呈现: f

我有以下表示Haskell中Lambda演算的代数数据类型:

data LExpr
    = Var String         -- variable
    | App LExpr LExpr    -- function application
    | Lam String LExpr   -- Lambda abstraction 
    deriving (Eq, Show)  
我正在尝试构建附带的fold函数。我熟悉代数数据类型的一般折叠形式,它可以以这种方式呈现:

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

这是正确的方法吗?如果没有,我错在哪里以及如何修复它?

我只提供一个提示

假设您有一个整数列表,类型如下:

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
。通过检查上面的
列表中发生的情况
类型,您现在应该能够填充空格。

查看您的签名,它与
foldr
不同,您应该命名已更改的变量。还记得将构造函数括在括号中<例如,code>v f go e有类型
String
String->a
LExpr->a
,和
LExpr
,这是一个无意义的调用链。@Guvante ok那么签名对应什么?
go(Var v)=v
go(App e1 e2)=go e1 go++go e2和
go(Lam ve)=v App go e
?我说得对吗?谢谢您的解释。@user4325010不,回想一下我们将
Nil
映射到
Nil
Cons
映射到
Cons
。所以
Var
必须映射到。。。特别是
Var v
必须映射到
。。。v
go(Var v)=Var v
go(App e1 e2)=App(go e1)(go e2)
go(Lam v e)=Lam v(go e)
?对吗?@user4325010完美!