Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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
Haskell 为什么使用复合运算符可以避免显式引用初始参数?_Haskell_Functional Programming - Fatal编程技术网

Haskell 为什么使用复合运算符可以避免显式引用初始参数?

Haskell 为什么使用复合运算符可以避免显式引用初始参数?,haskell,functional-programming,Haskell,Functional Programming,我似乎无法理解为什么下面的代码无法编译: decode :: [Bit] -> String decode xs = map (chr . bin2int) . (chop8 xs) 但以下内容将: decode :: [Bit] -> String decode = map (chr . bin2int) . chop8 当我们给第二个函数一个列表时,它应用chop8,然后映射chr。bin2输入到生成的列表中的元素 那么,为什么第一个示例不做同样的事情呢?我们不是在做同

我似乎无法理解为什么下面的代码无法编译:

decode :: [Bit] -> String
decode xs = map  (chr . bin2int) . (chop8 xs)
但以下内容将:

decode :: [Bit] -> String
decode = map  (chr . bin2int) . chop8 
当我们给第二个函数一个列表时,它应用chop8,然后映射chr。bin2输入到生成的列表中的元素

那么,为什么第一个示例不做同样的事情呢?我们不是在做同样的事情,只是在函数定义中给chop8参数吗


感谢

第二个版本使用了所谓的无点样式,不需要xs参数,因为表达式映射为chr。bin2int。chop8已经生成了一个[Bit]->String类型的函数,所以您只需将decode=设置为表达式的值

在第一个版本中,您显式地传递了xs参数,因此=右侧的表达式应为Int类型。由于您显式地将chop8应用于xs,因此结果是一个具体的列表,而不是一个函数

一种解决方案是将map显式应用于chop8的结果:

解码xs=映射chr。Bin2新台币8 x
请注意替换。使用$-apply function to parameter,而不是使用另一个函数编写函数,第二个版本使用所谓的无点样式,不需要xs参数,因为表达式映射为chr。bin2int。chop8已经生成了一个[Bit]->String类型的函数,所以您只需将decode=设置为表达式的值

在第一个版本中,您显式地传递了xs参数,因此=右侧的表达式应为Int类型。由于您显式地将chop8应用于xs,因此结果是一个具体的列表,而不是一个函数

一种解决方案是将map显式应用于chop8的结果:

解码xs=映射chr。Bin2新台币8 x 请注意替换。使用$-将函数应用于参数,而不是使用另一个函数组合函数的定义。这是钥匙

举一个简单的例子:

decode1, decode2 :: Int -> Char
decode1 x = chr . (abs x)
decode2 = chr . abs
现在,定义。是f。g=\a->f g a,因此我们可以在两个定义中使用它:

decode1 x = \a -> chr (abs x a)
decode2 = \x -> chr (abs x)
通过将lambda参数移动到模式匹配中,我们可以进一步简化此过程:

decode1 x a = chr (abs x a)
decode2 x = chr (abs x)
显然,decode2是正确的功能;decode1甚至不进行打字检查。abs只接受一个参数,但decode1使用2调用它!此外,decode1还有一个额外的参数a,这是我们不想要的。

的定义。这是钥匙

举一个简单的例子:

decode1, decode2 :: Int -> Char
decode1 x = chr . (abs x)
decode2 = chr . abs
现在,定义。是f。g=\a->f g a,因此我们可以在两个定义中使用它:

decode1 x = \a -> chr (abs x a)
decode2 = \x -> chr (abs x)
通过将lambda参数移动到模式匹配中,我们可以进一步简化此过程:

decode1 x a = chr (abs x a)
decode2 x = chr (abs x)

显然,decode2是正确的功能;decode1甚至不进行打字检查。abs只接受一个参数,但decode1使用2调用它!此外,decode1还有一个额外的参数a,这是我们不想要的。

您查看过类型和了吗。?同时向ghci索要:t chop8 vs:t chop8[]。由两个函数组成,chop8是一个函数,chop8xs不是。第一个代码段的正确版本是decode xs=map chr。bin2int。砍8个X。实际上,使用$operator避免括号更为惯用,但这是偶然的。你看到区别了吗?你看了类型和类型了吗。?同时向ghci索要:t chop8 vs:t chop8[]。由两个函数组成,chop8是一个函数,chop8xs不是。第一个代码段的正确版本是decode xs=map chr。bin2int。砍8个X。实际上,使用$operator避免括号更为惯用,但这是偶然的。你看到区别了吗?谢谢你,我现在明白了!总而言之只能应用于一个函数,不能应用于一个函数的结果!解码1不应该是ord。abs x,而不是ord。abs x?@bradrn,ord。abs x相当于map chr。bin2int。在原来的问题上加8个X。两者都不是有效的表达式。@IzaakWeiss我就是这么说的!事实上,我刚刚意识到Izakweiss确实说过decode1“甚至不进行打字检查”;我在写评论的时候没有注意到这一点。谢谢你,我现在明白了!总而言之只能应用于一个函数,不能应用于一个函数的结果!解码1不应该是ord。abs x,而不是ord。abs x?@bradrn,ord。abs x相当于map chr。bin2int。在原来的问题上加8个X。两者都不是有效的表达式。@IzaakWeiss我就是这么说的!事实上,我刚刚意识到Izakweiss确实说过decode1“甚至不进行打字检查”;当我写我的评论时,我错过了这个。谢谢你的帮助:复合运算符只能应用于函数,不能应用于列表!?是-列表最接近的方法是将它们连接起来组合和连接都遵守标识和关联规则,但这与本例无关。感谢您的帮助:组合运算符只能应用于函数,而不能应用于列表!?是的-列表最接近的事情是将它们连接在一起 连接遵循恒等式和结合定律,但这与本例无关。