Semigroupoid 和 Semigroup 之间的关系 类
Relation between the Semigroupoid and Semigroup classes
上周我一直在努力掌握Haskell的一些"core"类型和类型类(但一直在研究Haskell最多两周),我发现了一些让我烦恼的事情:
- a "Semigroupoid" 是 "Category" 的推广,这意味着任何类别都是平凡的 Semigroupoid,只需忽略它自己的身份并定义
o = (.)
- 也是 "Semigroup" 是 "Monoid" 的泛化,其含义与上面完全相同:只需要忽略 mempty 并定义
(<>) = mappend
仅这两个事实,以及 Semigroupoids 和 Semigroups 都只有组合元素的概念(semigroupoid-composition 与 semigroup-multiplication)并且 Category 和 Monoid 也有 "unity" 的概念( 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"有关?
如有任何见解,我们将不胜感激。
如果它只需要 FlexibleInstances
没有人会介意(该扩展是完全无害的),但不幸的是,一旦您添加足够有趣的其他实例,它也会导致需要一个非常无害的其他扩展。即,
{-# LANGUAGE FlexibleInstances #-}
import Control.Category (Category)
instance Category c => Monoid (c a a)
data Nontrivial s q = Nontrivial {
someLabel :: String
, someValues :: [(s, Int)]
, otherValues :: Maybe (String, q)
, moreStuff :: ({-...-})
}
instance (Monoid s, Monoid q) => Monoid (Nontrivial s q) where
mempty = Nontrivial "" [] Nothing ()
main = case mempty :: Nontrivial String String of
Nontrivial _ _ _ _ -> return ()
不编译:
$ runhaskell wtmpf-file6064.hs
wtmpf-file6064.hs:17:13:
Overlapping instances for Monoid (Nontrivial String String)
arising from a use of ‘mempty’
Matching instances:
instance Category c => Monoid (c a a)
-- Defined at wtmpf-file6064.hs:5:10
instance (Monoid s, Monoid q) => Monoid (Nontrivial s q)
-- Defined at wtmpf-file6064.hs:14:10
In the expression: mempty :: Nontrivial String String
In the expression:
case mempty :: Nontrivial String String of {
Nontrivial _ _ _ _ -> return () }
In an equation for ‘main’:
main
= case mempty :: Nontrivial String String of {
Nontrivial _ _ _ _ -> return () }
现在,您可以通过添加 {-# OVERLAPPABLE #-}
Pragmas 使其正常工作,但这是一些相当繁琐的工作,可能会导致奇怪的行为。强烈避免这种情况。
上周我一直在努力掌握Haskell的一些"core"类型和类型类(但一直在研究Haskell最多两周),我发现了一些让我烦恼的事情:
- a "Semigroupoid" 是 "Category" 的推广,这意味着任何类别都是平凡的 Semigroupoid,只需忽略它自己的身份并定义
o = (.)
- 也是 "Semigroup" 是 "Monoid" 的泛化,其含义与上面完全相同:只需要忽略 mempty 并定义
(<>) = mappend
仅这两个事实,以及 Semigroupoids 和 Semigroups 都只有组合元素的概念(semigroupoid-composition 与 semigroup-multiplication)并且 Category 和 Monoid 也有 "unity" 的概念( 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"有关?
如有任何见解,我们将不胜感激。
如果它只需要 FlexibleInstances
没有人会介意(该扩展是完全无害的),但不幸的是,一旦您添加足够有趣的其他实例,它也会导致需要一个非常无害的其他扩展。即,
{-# LANGUAGE FlexibleInstances #-}
import Control.Category (Category)
instance Category c => Monoid (c a a)
data Nontrivial s q = Nontrivial {
someLabel :: String
, someValues :: [(s, Int)]
, otherValues :: Maybe (String, q)
, moreStuff :: ({-...-})
}
instance (Monoid s, Monoid q) => Monoid (Nontrivial s q) where
mempty = Nontrivial "" [] Nothing ()
main = case mempty :: Nontrivial String String of
Nontrivial _ _ _ _ -> return ()
不编译:
$ runhaskell wtmpf-file6064.hs
wtmpf-file6064.hs:17:13:
Overlapping instances for Monoid (Nontrivial String String)
arising from a use of ‘mempty’
Matching instances:
instance Category c => Monoid (c a a)
-- Defined at wtmpf-file6064.hs:5:10
instance (Monoid s, Monoid q) => Monoid (Nontrivial s q)
-- Defined at wtmpf-file6064.hs:14:10
In the expression: mempty :: Nontrivial String String
In the expression:
case mempty :: Nontrivial String String of {
Nontrivial _ _ _ _ -> return () }
In an equation for ‘main’:
main
= case mempty :: Nontrivial String String of {
Nontrivial _ _ _ _ -> return () }
现在,您可以通过添加 {-# OVERLAPPABLE #-}
Pragmas 使其正常工作,但这是一些相当繁琐的工作,可能会导致奇怪的行为。强烈避免这种情况。