Endoid为Monoid [英] Endofunction as Monoid

查看:109
本文介绍了Endoid为Monoid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


$ b

  { - #LANGUAGE FlexibleInstances# - } 

实例Monoid(a - > a)其中
mempty = id
mappend fg = f。 g

预计 id<> id 等于 id。 id



然而,当(id<> id)1 这个错误:

 约束中的非类型变量参数:Monoid(a  - > a)
code>

我该如何更改以运行它?


$ b

这只是为了更好地理解monoids和Haskell类型类,不适用于任何实际用法。

解决方案

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

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

instance { - #OVERLAPPING# - } Monoid(a - > a)其中
mempty = id
mappend fg = f。 g

然后,上面的实例将被调用用于 a - >一个,即使 a 是一个Monoid:

  \> (id<> id)1 
1
\> (id> id)[1]
[1]

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

  \> ((:[])<>(:[]))1 
[1,1]

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


I'm trying this (for learning purposes):

{-# LANGUAGE FlexibleInstances #-}

instance Monoid (a -> a) where
  mempty = id
  mappend f g = f . g

expecting id <> id to be equal to id . id

However, with (id <> id) 1 I receive this error:

Non type-variable argument in the constraint: Monoid (a -> a)

What should I change to run it?

It's just to understand monoids and Haskell typeclasses better, not for any practical usage.

解决方案

This will need {-# OVERLAPPING #-} pragma since GHC.Base has an instance for Monoid (a -> b) when b is a Monoid:

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

instance {-# OVERLAPPING #-} Monoid (a -> a) where
    mempty = id
    mappend f g = f . g

then, above instance will be invoked for a -> a, even if a is a Monoid:

\> (id <> id) 1
1
\> (id <> id) [1]
[1]

whereas with Monoid b => a -> b the instance from GHC.Base will be invoked:

\> ((:[]) <> (:[])) 1
[1,1]

Note that Data.Monoid provides an exact same instance as yours for a -> a but there the overlap is bypassed using newtype Endo a.

这篇关于Endoid为Monoid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆