Haskell 帮助理解无点代码
在玩游戏的时候,我看到了一段我似乎无法理解的代码Haskell 帮助理解无点代码,haskell,pointfree,Haskell,Pointfree,在玩游戏的时候,我看到了一段我似乎无法理解的代码 :pl map (\x -> x * x) [1..10] -- map (join (*)) [1..10] 我的主要问题是我不明白join在这里是如何工作的。据我所知,它“移除”了一层一元包装(m(ma)到ma)。我想这可以归结为[1..10]>=(\x->[x*x]),但我不知道“额外层”是如何引入的。我得到了join x=x>=id,但我仍然停留在如何“复制”每个值上,以便(*)获得两个参数。这已经困扰了我大约半个小时了,我对自己
:pl map (\x -> x * x) [1..10]
-- map (join (*)) [1..10]
我的主要问题是我不明白join
在这里是如何工作的。据我所知,它“移除”了一层一元包装(m(ma)
到ma
)。我想这可以归结为[1..10]>=(\x->[x*x])
,但我不知道“额外层”是如何引入的。我得到了join x=x>=id
,但我仍然停留在如何“复制”每个值上,以便(*)
获得两个参数。这已经困扰了我大约半个小时了,我对自己很恼火,因为我觉得我有所有的拼图块,但似乎无法将它们组合在一起
另外,别担心,我不会真的使用这个无点版本,这纯粹是好奇,是为了更好地理解Haskell。
join
使用Monad
的实例作为(>)a
,如Control.Monad.Instances
中所定义。该实例类似于Reader
,但没有显式包装器。定义如下:
instance Monad ((->) a) where
-- return :: b -> (a -> b)
return = const
-- (>>=) :: (a -> b) -> (b -> a -> c) -> (a -> c)
f >>= g = \x -> g (f x) x
如果现在使用此实例减少join
:
join
(>>= id)
flip (\f g x -> g (f x) x) (\a -> a)
(\f x -> (\a -> a) (f x) x)
(\f x -> f x x)
如您所见,
(>)a
的实例使连接到两次应用参数的函数。正因为如此,join(*)
只是\x->x*x
你也可以从参数计算出来。在monad(>)a
中,join
的类型为((>)a)((>)a b)->((>)a b)
,简化为(a->a->b)->a->b
。很明显,join
能够获得b
的唯一方法就是将a
馈送到函数两次。(当然,除了使用底部值)。@hammar难道没有一个程序可以通过查看类型签名来找出函数唯一合理的定义吗?(如果可能的话)@fuzzxl:是的。这个软件包似乎有点过时了。我上传了一个新版本的Djinn。谢谢,这正是我所缺少的!:-)实际上,我玩了一会儿((->)a)
的monad实例,但没有取得任何进展,可能是因为这里快凌晨2点了,我很累。再次感谢<代码>连接::m(MA)->MA
并不完全“移除”一层一元包装,更准确的说法是它将两层挤压成一层。因此得名,事实上。。。