Haskell:之前的 return 被之后的 monad 抵消了。如何?
Haskell: a return before is cancelled out by a monad after. How?
如何理解 return 1 getLine
语句?它通过了类型检查,看起来与 1
相同。 getLine
和 return
如何相互“抵消”?这对我来说完全没有意义。
Prelude> :t return 1
return 1 :: (Monad m, Num a) => m a
Prelude> :t return 1 getLine -- why is it not a type error?
return 1 getLine :: Num t => t
Prelude> return 1 getLine
1 -- whatever happened to getLine?
此外,为什么最终产品是“纯”的,即使它涉及 getLine
?
如果你写return 1 getLine
,那意味着return 1
应该是一个以getLine
为参数的函数。
我们很幸运,因为有一个instance for Monad
with a function ((->) r)
[src]。确实:
-- | @since 2.01
instance Applicative ((->) r) where
pure = const
(<*>) f g x = f x (g x)
liftA2 q f g x = q (f x) (g x)
-- | @since 2.01
instance Monad ((->) r) where
f >>= k = \ r -> k (f r) r
(->) r
是 r -> …
的更规范的形式。因此它是一个以 r
作为参数类型的函数,如果应用于类型参数 a
例如,则 ((->) r) a
等同于 r -> a
.
对于 Monad
的这个实例,return
与 pure
具有相同的实现,即 const
。因此,这意味着:
return 1 getLine
相当于:
const 1 getLine
→ (\_ -> 1) getLine
→ 1
How do I understand the statement return 1 getLine
?
首先注意到 return 1 getLine
实际上是 (return 1)
getLine
.
这意味着 return 1
是一个函数,因为它接受一个额外的参数,并且函数也是一元值 (这就是为什么它不是类型错误)。
所以我们必须统一
return :: Monad m => a -> m a
return 1 :: (Monad m, Num a) => m a
return 1 :: Num a => r -> a -- Monad (r ->)
所以 m a ~ r -> a
和 m ~ (->) r
(这是写 (r ->)
的正确方法,它本身就是一个无效的语法)。
对于函数,return = const
所以我们有
return 1 getline
= const 1 getline
= const 1 undefined
= 1
因为const
定义为
const :: a -> b -> a
const x y = x
(这就是 getLine
被忽略的方式)。
一般来说,函数 Monad 实例的定义使得
do { a <- f ; b <- foo a ; return (bar a b) } x
与
相同
let { a = f x ; b = foo a x } in bar a b -- const (bar a b) x
这就是 return
被定义为 const
的原因。
这意味着 return
和 getLine
而不是 “相互抵消”。这只是 return
所做的,因为它被应用于第二个参数, 不管是什么 ,即使是 undefined
.
所以 getLine
属于 IO
“monad”,正如您在问题中所写的那样, 无关 。 Haskell 中的一切都是一个值,getLine
也只是另一个值。这是一个纯粹的价值;它只是描述了一个“不纯”的 I/O 动作,但它本身只是另一个值,在这里仅用作参数。只有当 getLine
出现在 main
的适当位置(或者在 main 中递归出现的其他代码中)时,它才是“运行”,即它描述的计算才真正执行。这里不是这样的。
这里使用的 monad 是这个 return
所属的函数 monad。
至于纯度问题,单子本身既不是纯的也不是不纯的。实现 Monad 的类型可以是 纯 或 不纯。函数恰好是纯的。
Monad 所做的是分离 纯与潜在的不纯。
但这实际上也是函子所做的。 Monads,具体来说,允许混合链接 pure-->impure-->pure-->impure-->....位,同时保持它们的分离(同样,“不纯”位实际上也可以是纯的;重要的是两个“世界”之间的分离)。
如何理解 return 1 getLine
语句?它通过了类型检查,看起来与 1
相同。 getLine
和 return
如何相互“抵消”?这对我来说完全没有意义。
Prelude> :t return 1
return 1 :: (Monad m, Num a) => m a
Prelude> :t return 1 getLine -- why is it not a type error?
return 1 getLine :: Num t => t
Prelude> return 1 getLine
1 -- whatever happened to getLine?
此外,为什么最终产品是“纯”的,即使它涉及 getLine
?
如果你写return 1 getLine
,那意味着return 1
应该是一个以getLine
为参数的函数。
我们很幸运,因为有一个instance for Monad
with a function ((->) r)
[src]。确实:
-- | @since 2.01 instance Applicative ((->) r) where pure = const (<*>) f g x = f x (g x) liftA2 q f g x = q (f x) (g x) -- | @since 2.01 instance Monad ((->) r) where f >>= k = \ r -> k (f r) r
(->) r
是 r -> …
的更规范的形式。因此它是一个以 r
作为参数类型的函数,如果应用于类型参数 a
例如,则 ((->) r) a
等同于 r -> a
.
对于 Monad
的这个实例,return
与 pure
具有相同的实现,即 const
。因此,这意味着:
return 1 getLine
相当于:
const 1 getLine
→ (\_ -> 1) getLine
→ 1
How do I understand the statement
return 1 getLine
?
首先注意到 return 1 getLine
实际上是 (return 1)
getLine
.
这意味着 return 1
是一个函数,因为它接受一个额外的参数,并且函数也是一元值 (这就是为什么它不是类型错误)。
所以我们必须统一
return :: Monad m => a -> m a
return 1 :: (Monad m, Num a) => m a
return 1 :: Num a => r -> a -- Monad (r ->)
所以 m a ~ r -> a
和 m ~ (->) r
(这是写 (r ->)
的正确方法,它本身就是一个无效的语法)。
对于函数,return = const
所以我们有
return 1 getline
= const 1 getline
= const 1 undefined
= 1
因为const
定义为
const :: a -> b -> a
const x y = x
(这就是 getLine
被忽略的方式)。
一般来说,函数 Monad 实例的定义使得
do { a <- f ; b <- foo a ; return (bar a b) } x
与
相同let { a = f x ; b = foo a x } in bar a b -- const (bar a b) x
这就是 return
被定义为 const
的原因。
这意味着 return
和 getLine
而不是 “相互抵消”。这只是 return
所做的,因为它被应用于第二个参数, 不管是什么 ,即使是 undefined
.
所以 getLine
属于 IO
“monad”,正如您在问题中所写的那样, 无关 。 Haskell 中的一切都是一个值,getLine
也只是另一个值。这是一个纯粹的价值;它只是描述了一个“不纯”的 I/O 动作,但它本身只是另一个值,在这里仅用作参数。只有当 getLine
出现在 main
的适当位置(或者在 main 中递归出现的其他代码中)时,它才是“运行”,即它描述的计算才真正执行。这里不是这样的。
这里使用的 monad 是这个 return
所属的函数 monad。
至于纯度问题,单子本身既不是纯的也不是不纯的。实现 Monad 的类型可以是 纯 或 不纯。函数恰好是纯的。
Monad 所做的是分离 纯与潜在的不纯。
但这实际上也是函子所做的。 Monads,具体来说,允许混合链接 pure-->impure-->pure-->impure-->....位,同时保持它们的分离(同样,“不纯”位实际上也可以是纯的;重要的是两个“世界”之间的分离)。