Endofunction为Monoid

Iva*_*nin 4 haskell monoids

我正在尝试这个(用于学习目的):

{-# LANGUAGE FlexibleInstances #-}

instance Monoid (a -> a) where
  mempty = id
  mappend f g = f . g
Run Code Online (Sandbox Code Playgroud)

期望id <> id等于id . id

但是,(id <> id) 1我收到此错误:

Non type-variable argument in the constraint: Monoid (a -> a)
Run Code Online (Sandbox Code Playgroud)

我应该改变什么来运行它?

这只是为了更好地理解monoids和Haskell类型类,而不是用于任何实际用途.

beh*_*uri 5

这将需要{-# OVERLAPPING #-}编译指示,因为GHC.Base有一个实例,Monoid (a -> b)当b是一个Monoid时:

{-# LANGUAGE FlexibleInstances #-}
import Data.Monoid (Monoid, mempty, mappend, (<>))

instance {-# OVERLAPPING #-} Monoid (a -> a) where
    mempty = id
    mappend f g = f . g
Run Code Online (Sandbox Code Playgroud)

然后,a -> a即使a是Monoid ,也会调用上面的实例:

\> (id <> id) 1
1
\> (id <> id) [1]
[1]
Run Code Online (Sandbox Code Playgroud)

Monoid b => a -> b来自GHC.Base的实例将被调用:

\> ((:[]) <> (:[])) 1
[1,1]
Run Code Online (Sandbox Code Playgroud)

请注意,Data.Monoid提供与您的实例完全相同的实例,a -> a但使用时会绕过重叠newtype Endo a.

  • 没有重叠!没有!而且,现有的实例让我感到难过.我更喜欢`instance a~b => Monoid(a - > b)`,它与`instance Category( - >)`精确匹配.`on`版本应该有一个newtype包装器. (2认同)