在上周,我一直在尝试掌握 Haskell 的一些“核心”类型和类型类(但总共学习 Haskell 最多两周),我发现了一些让我烦恼的东西:
- “Semigroupoid”是“Category”的概括,这意味着任何类别都是平凡的 Semigroupoid,只需忽略它自己的身份并定义
o = (.)
- 同样,“半群”是“Monoid”的概括,其含义与上述完全相同:只需忽略 mempty 并定义
(<>) = mappend
仅这两个事实,以及 Semigroupoids 和 Semigroups 都只有组合元素的概念(semigroupoid-composition vs semigroup-multiplication)并且 Category 和 Monoid 都具有“统一”(identity vs unit element)的概念带来了请注意,可以将 Semigroupoids 和 Semigroups 以及 Categories 和 Monoids 之间的关系表达如下
import Prelude hiding (id, (.))
import Data.Semigroupoid
import Data.Semigroup
import Control.Category
import Data.Monoid
instance Semigroupoid c => Semigroup (c a a) where
(<>) = o
instance Category c => Monoid (c a a) where
mempty = id
mappend = (.)
main = putStrLn "Does not type-check!"
现在,我不确定为什么它不能编译;ghc 编译器说:
All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
但碰巧包括
{-# LANGUAGE FlexibleInstances #-}
在文件的顶部修复了所有问题。
上面表达的关系似乎没有在库中构建,而 Semigroupoid 和 Category 之间以及 Semigroup 和 Monoid 之间的关系是内置的。
有什么具体原因吗,我只是想念它吗?
也许它与神秘的“FlexibleInstances”有关?
任何见解将不胜感激。