List 这种奇怪的单子绑定是如何工作的?
这可能是一个非常noob的问题,但我在Haskell中使用bind操作符时遇到了一种使用它重复字符串的方法List 这种奇怪的单子绑定是如何工作的?,list,haskell,return,bind,monads,List,Haskell,Return,Bind,Monads,这可能是一个非常noob的问题,但我在Haskell中使用bind操作符时遇到了一种使用它重复字符串的方法 [1..3] >>= const "Hey" -- Yields "HeyHeyHey" [1..3] >>= return "Hey" -- Also yields the same result 我理解>=(\\\->return“Hey”)将如何产生[“Hey”,“Hey”,“Hey”],但我不理解为什么(\\\\\>“Hey”)重复字符串,或者为什么>=返
[1..3] >>= const "Hey"
-- Yields "HeyHeyHey"
[1..3] >>= return "Hey"
-- Also yields the same result
我理解>=(\\\->return“Hey”)
将如何产生[“Hey”,“Hey”,“Hey”]
,但我不理解为什么(\\\\\>“Hey”)
重复字符串,或者为什么>=返回“Hey”
做同样的事情
我理解>=(\\\->返回“Hey”)
将如何产生[“Hey”,“Hey”,“Hey”]
对<代码>返回“嘿”在本例中与[“嘿”]
相同,因为
instance Monad [] where
return x = [x]
所以
现在,还可以在lambda中使用列表结果来编写>=(\\\->“嘿”)
,因为字符串只是字符列表
([1..3] >>= \_ -> "Hey")
≡ ([1..3] >>= \_ -> ['H','e','y'])
≡ ['H','e','y'] ++ ['H','e','y'] ++ ['H','e','y']
≡ ['H','e','y','H','e','y','H','e','y']
≡ "HeyHeyHey"
至于>>=返回“嘿”
,那是另一头野兽。return
在这里属于一个完全不同的单子,即函数函子
因此很明显,([1..3]>=const“Hey”)
和([1..3]>=return“Hey”)
给出了相同的结果:在这个例子中,return
只是const
的另一个名称
我理解>=(\\\->返回“Hey”)
将如何产生[“Hey”,“Hey”,“Hey”]
对<代码>返回“嘿”在本例中与[“嘿”]
相同,因为
instance Monad [] where
return x = [x]
所以
现在,还可以在lambda中使用列表结果来编写>=(\\\->“嘿”)
,因为字符串只是字符列表
([1..3] >>= \_ -> "Hey")
≡ ([1..3] >>= \_ -> ['H','e','y'])
≡ ['H','e','y'] ++ ['H','e','y'] ++ ['H','e','y']
≡ ['H','e','y','H','e','y','H','e','y']
≡ "HeyHeyHey"
至于>>=返回“嘿”
,那是另一头野兽。return
在这里属于一个完全不同的单子,即函数函子
因此很明显,
([1..3]>=const“Hey”)
和([1..3]>=return“Hey”)
给出了相同的结果:在这个例子中,return
只是const
的另一个名称 此处使用的return
不是用于列表monad,而是用于函数monad,其中该定义包含:
return x = \_ -> x
因此,这与:
[1,2,3] >>= (\_ -> "Hey")
由于列表的(>>=)
与concatMap
相同,我们有:
concatMap (\_ -> "Hey") [1,2,3]
您能理解为什么这会产生“HeyHeyHey”?此处使用的
返回值不适用于列表monad,而是适用于函数monad,其中包含此定义:
return x = \_ -> x
因此,这与:
[1,2,3] >>= (\_ -> "Hey")
由于列表的(>>=)
与concatMap
相同,我们有:
concatMap (\_ -> "Hey") [1,2,3]
你能理解为什么这会产生“HeyHeyHey”
?我一直很好奇人们如何看待任何给定的haskell表达式(例如[1..3]>>返回“Hey”
)并知道特定函数的实现(例如返回
)正在使用–我怎么知道函数Functor的return
在本例中被使用?@naomik-查看类型。从[1..3]
我们知道>=
的左侧是Num a=>[a]
类型,这意味着>=
在实例Monad[]
中定义,其右侧必须是Num a=>a->[b]
类型。我们已经知道了return“Hey”::Monad m=>m String
,所以现在我们可以声明m String~a->[b]
,如果我们使用b~Char
和m-a
,那么return
必须由实例Monad(-a)定义
@rampion当我开始理解它时,脸上露出了笑容。我仍然有两个问题–1)如何准确地解释(例如)m String~a->[b]
中的~
?2)多个返回
实现是否可能满足所需的类型?1)~
是类型级别相等。你会在我给出的波浪式类型推理证明和类型约束(例如(Show a,Monad m,ma~String)
)中看到它。2) 在这个特定的示例中,没有,因为我们将m
缩小为numa=>(>)a
,而实例Monad((>)a
不依赖于a
。如果存在单独的实例Monad((->)Int
和实例Monad((->)Float)
相反,这将是一个不同的答案。两者都会匹配。@Rapion感谢您的帮助–您完成过这方面的工作吗?这类问题对我来说非常有趣,我想看看您的工作是否是开源的^ ^我一直很好奇如何看待任何给定的haskell表达式(例如[1..3]>>返回“嘿”
)并知道某个特定函数(例如return
)正在使用哪个实现–我怎么知道函数Functor的return
在这种情况下被使用?@naomik-查看类型。从[1..3]
我们知道>=
的左侧是Num a=>[a]类型
,这意味着>=
是在实例Monad[]
中定义的,它的右侧必须是Num a=>a->[b]
类型。我们已经知道返回“Hey”::Monad m=>m String
,所以现在我们可以声明m String~a->[b]
,如果我们取b~Char
和m-a
,我们可以匹配它,所以返回
必须由实例Monad((>)a)
@rampion定义。当我开始理解它时,我脸上露出笑容。我仍然有两个问题:1)我如何准确地解释(例如)m字符串~a->[b]
?2)多个返回
实现是否可能满足所需的类型?1)~
是类型级别相等。你会在我给出的波浪式类型推理证明和类型约束(例如(Show a,Monad m,ma~String)
)中看到它。2) 在这个特定的示例中,没有,因为我们将m
缩小为numa=>(>)a
,而实例Monad((>)a
不依赖于a
。