我似乎不明白为什么下面的代码不能编译:
decode :: [Bit] -> String
decode xs = map (chr . bin2int) . (chop8 xs)
但下面的代码会:
decode :: [Bit] -> String
decode = map (chr . bin2int) . chop8
当我们给第二个函数一个列表时,它对它应用chop8,然后映射(chr。bin2int)添加到生成的列表中的元素。
那么,为什么第一个示例不做同样的事情呢?我们是不是在做同样的事情,而只是在函数定义中给chop8参数?
谢谢
发布于 2019-06-19 03:03:53
(.)
的定义是这里的关键。
举个简单的例子:
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
,这是我们不想要的。
发布于 2019-06-19 03:02:14
第二个版本,使用所谓的无指针样式,不需要"xs“参数,因为表达式map (chr . bin2int) . chop8
已经生成了一个[Bit] -> String
类型的函数-所以您所能做的就是将decode =
设置为表达式的值。
在第一个版本中,您显式地传递了xs
参数,因此=
右侧的表达式应该是Int
类型。因为您显式地将chop8应用于X,所以结果是一个具体的列表,而不是一个函数。
一种解决方案是显式地将map应用于chop8的结果:
decode xs = map (chr . bin2int) $ (chop8 xs)
请注意,将.
替换为$
-“将函数应用于参数”而不是“将函数与另一个函数组合”
https://stackoverflow.com/questions/56655146
复制相似问题