"Int - > Int - > Ordering"的Monoid实例分辨率

m09*_*m09 6 haskell typeclass

我打算在明天我将给Haskell的一个小介绍中展示类型类的强大功能的一个例子.

我以为我会仔细检查我要呈现的内容,因为我不是100%自信.

所以,假设我有两个功能:

firstSort :: Int -> Int -> Ordering
firstSort a b = compare (even a) (even b)

secondSort :: Int -> Int -> Ordering
secondSort = compare
Run Code Online (Sandbox Code Playgroud)

现在,由于他们的Monoid实例,我可以将这两种结合起来:

sort :: Int -> Int -> Ordering
sort = firstSort <> secondSort
Run Code Online (Sandbox Code Playgroud)

现在我要确认的是mappend两种类型中使用的过程.

根据我的理解,它的工作方式如下:

  • 首先是实例:

    instance Monoid b => Monoid (a -> b) where
            mempty _ = mempty
            mappend f g x = f x `mappend` g x
    
    Run Code Online (Sandbox Code Playgroud)

    用来.这是通过实例化a该实例来完成的(Int -> Int).此外,声明mappend让我困惑了一段时间,因为它需要3个参数而不是2但后来我记得那(a -> b) -> (a -> b) -> (a -> b)实际上是相同的(a -> b) -> (a -> b) -> a -> b.

    感谢这个实例,我们得到的firstSort <> secondSort是:

    \a b -> (firstSort a b) <> (secondSort a b)
    
    Run Code Online (Sandbox Code Playgroud)
  • 那么实例:

    instance Monoid Ordering where
            mempty         = EQ
            LT `mappend` _ = LT
            EQ `mappend` y = y
            GT `mappend` _ = GT
    
    Run Code Online (Sandbox Code Playgroud)

    mappend结果一起使用firstSortsecondSort

所以,概括起来讲,这将匹配Monoid b => Monoid (a -> b)实例与b = Orderinga = (Int -> Int)事后的Monoid Ordering实例.

那是对的吗?

Nik*_*kov 7

是.你已经正确地结束了.

由于Int -> Int -> Ordering是curry,它可以看作是一个参数的函数,它返回另一个函数.即:

Int -> (Int -> Ordering)
Run Code Online (Sandbox Code Playgroud)

因此,编译器Monoid分三步解析实例:

 Value Type               | Monoid Instance
--------------------------|---------------------------
 Int -> (Int -> Ordering) | instance Monoid b => Monoid (a -> b)
 Int -> Ordering          | instance Monoid b => Monoid (a -> b)
 Ordering                 | instance Monoid Ordering
Run Code Online (Sandbox Code Playgroud)


Emi*_*mil 7

让我们来看看.我不认为a你想要的是(Int -> Int)因为当没有parantheses时函数类型与右边相关联.在你的情况下,类型是

firstSort :: Int -> (Int -> Bool)
secondSort :: Int -> (Int -> Bool)
Run Code Online (Sandbox Code Playgroud)

所以,这里有一些有趣的事情.当你连接这两个函数时,它实际上是两次!首先,a它只是第一个Int而且bInt -> Bool,所以我们必须使用Monoid结构Int -> Bool.但要做到这一点,我们必须再做同样的事情,所以aIntbBool.

firstSort <> secondSort = \a -> (firstSort a) <> (secondSort a) 
                        = \a -> (\b -> (firstSort a b) <> (secondSort a b))
Run Code Online (Sandbox Code Playgroud)

但最终结果仍然与你得出的结果相同:

                        = \a b -> (firstSort a b) <> (secondSort a b)
Run Code Online (Sandbox Code Playgroud)