功能组成提示

时间:2012-08-19 08:29:38

标签: haskell monads type-inference function-composition reader-monad

只是寻找解释以下作文的工作原理:

(=<<) . return

,其中

(=<<) ::       (a -> m b) -> m a -> m b
return :: a -> m a
(.) :: (b -> c) -> (a -> b) -> a -> c

最终类型:

GHCi> :t (=<<) . return
(=<<) . return :: Monad m => m b -> m a -> m b

我无法理解如何将 m a (a - &gt; m b)匹配,即。如何将 return 的结果应用于(=&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; em&gt

2 个答案:

答案 0 :(得分:7)

解释是:

  1. 您的return(可能是意外)与您的=<<不同的monad。
  2. 它使用的monad是读者monad (->) r
  3. 编译器尝试将return :: c -> m' c的结果与(a -> m b) -> m a -> m b的第一个参数统一,因此unify m' ca -> m b统一。唯一的可能性是m'是某些(->) r的读者monad r。接下来,它尝试将(->) r c与(转换为前缀表示法)(->) a (m b)统一起来,通过将r设置为a并将c设置为{{}来解决此问题。 1}}。因此,在统一之后,编译器将获得最通用的类​​型

    m b

    或以通常的中缀符号

    return :: (m b) -> ((->) a (m b))
    

    另见:


    修改:要定义monad,我们需要(部分应用)kind Monad ((->) r)类型。这些几乎总是部分应用的数据构造函数,但在这种特殊情况下,我们将* -> *视为一个类型运算符,它接受2个类型的参数并创建一个新类型(函数类型)。因此,对于任何给定类型->,部分应用的表达式r是一种类型(->) r。事实证明,如何在其上描述monad操作有一种简单的方法。请参阅解释它的Control.Reader monad和this article* -> *的monad操作的实现方式与Reader完全相同,唯一的区别是(->)将操作包装为不同的数据类型。

答案 1 :(得分:1)

我再次与涂鸦一起并排放置东西以帮助视觉理解:

g = ((=<<) . return)   {-

((=<<) . return) x y 
         ===   (=<<)    (return x)    y               return :: a' -> m' a'
               (=<<) :: (a -> m b) -> m a -> m b      return x :: m' a' , x :: a'
                          m'  a'                      m' ~ ((->) a) , a' ~ m b 

return x === const x             -- instance Monad ((->) a) where return = const
g x y === y >>= (\_ -> x) === y >> x   (!!)
-}

g :: m b -> m a -> m b

事实证明(并且可能从类型签名中显而易见), g === flip (>>)

Prelude> ((=<<).return) [1] "xyz"   -- ===  (=<<) (const [1]) "xyz" 
                                    -- ===  "xyz" >>= const [1]
                                    -- ===  "xyz" >> [1]
                                    -- ===  (>> [1]) "xyz"
[1,1,1]