'.'之间有什么区别?和'<<<'执行功能组合时?

tce*_*act 2 haskell hindley-milner category-abstractions

我正在尝试在Haskell中执行函数组合,我不确定哪个运算符是正确的运算符.

文档包含这两种类型的签名:

(.) :: (b -> c) -> (a -> b) -> a -> c 
(<<<) :: Category cat => cat b c -> cat a b -> cat a c 
Run Code Online (Sandbox Code Playgroud)

显然,这两个选项之间的区别在于是否存在Category cat,但是这个注释表示什么,以及我应该如何使用这些信息来选择一个运算符而不是另一个?

在比较其他两个运算符时,我还注意到上述两个签名的第三个变体:

(>>) :: forall a b. m a -> m b -> m b 
(>>>) :: Category cat => cat a b -> cat b c -> cat a c
Run Code Online (Sandbox Code Playgroud)

forall注释意味着什么- >>用于第三种情况?

che*_*ner 6

首先,您应该认识到,(.)在Prelude中以函数特定的形式定义

(.) :: (b -> c) -> (a -> b) -> a -> c 
Run Code Online (Sandbox Code Playgroud)

以及Category该类提供的更通用的功能:

class Category cat where
    -- | the identity morphism
    id :: cat a a

    -- | morphism composition
    (.) :: cat b c -> cat a b -> cat a c
Run Code Online (Sandbox Code Playgroud)

(->)实例Category清楚地表明,这两个是功能相同:

instance Category (->) where
    id = GHC.Base.id
    (.) = (GHC.Base..)
Run Code Online (Sandbox Code Playgroud)

定义(<<<)清楚地表明它只是一个同义词(.)

-- | Right-to-left composition
(<<<) :: Category cat => cat b c -> cat a b -> cat a c
(<<<) = (.)
Run Code Online (Sandbox Code Playgroud)

旨在与(>>>)操作员对称.你可以写任何一个f >>> gg <<< f哪个,对你的特定用途更有意义.


(>>)是一个完全不同的运算符(至少,只要你没有深入研究monad理论).(>>)是一个版本(>>=)忽略第一个操作数的结果,仅使用它的效果.

x >> y == x >>= (\_ -> y)
Run Code Online (Sandbox Code Playgroud)

  • 历史记录:如果不是"Control.Arrow"中的遗产,``(<<<)`可能不存在. (3认同)
  • 您可能想要提及与`> =>`,`<= <`和`Kleisli`的连接,它间接地弥合了`>>>`和`>>`之间的差距. (2认同)