Haskell中的`(->) a`单子是什么?

3

1
你可以用“函数单子”或“读取器单子”来称呼它(尽管后者通常指的是显式命名的等效物)。 - leftaroundabout
http://learnyouahaskell.com/a-fistful-of-monads#the-monad-type-class - wit
2个回答

4
这是一个Reader monad。你可以把它想象成…
type Reader r = (->) r -- Reader r a == (->) r a == r -> a
instance Monad (Reader r) where
  return a = const a            
  m >>= f = \r -> f (m r) r    

并进行以下计算:

double :: Num r => Reader r r
double = do
  v <- id
  return (2*v)

2
用例:您可以使用此功能为代码提供配置文件。或者在某些类型检查器中,跟踪环境。 - daniel gratzer

4

这是函数Monad,有点难理解。顺便说一下,它有时被称为Reader Monad。我认为最好的方法是通过一个例子来说明它的工作原理:

f1 :: Double -> Double
f1 x = 10 * x + x ** 2 + 3 * x ** 3

f2 :: Double -> Double
f2 = do
    x1 <- (10 *)
    x2 <- (** 2)
    x3 <- (** 3)
    return $ x1 + x2 + 3 * x3

如果你尝试这两种方法,你会发现它们都返回相同的结果。那么究竟发生了什么呢?当你从一个函数中“提取”一个值时,你得到的可以被认为是其“返回值”的值。我在引号中加上了它,因为当你从这个monad中return一个值时,你返回的是一个函数。
对于像这样的例子,f2的隐式参数会作为一个隐式参数传递给每一个<-。如果你有很多带有相同参数的子表达式,它可以非常有用。正如Reader monad一样,它通常用于提供只读配置值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接