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
List 这种奇怪的单子绑定是如何工作的?_List_Haskell_Return_Bind_Monads - Fatal编程技术网

List 这种奇怪的单子绑定是如何工作的?

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”)重复字符串,或者为什么>=返

这可能是一个非常noob的问题,但我在Haskell中使用bind操作符时遇到了一种使用它重复字符串的方法

[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