我正在尝试这个(用于学习目的):
{-# 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类型类,而不是用于任何实际用途.
这将需要{-# 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.