我有一个这样定义的类型:
newtype PrimeSet a = P Integer
deriving Eq
我还定义了一个将素数集转换为列表的函数,假设它的类型参数是Integral
.
toList :: Integral a => PrimeSet a -> [a]
我现在该给予什么PrimeSet
a Foldable
实例,所以这是我的第一次尝试(导入后fold
from Data.Foldable
):
instance Foldable PrimeSet where
foldMap f = fold . map f . toList
然而,这不起作用,编译器告诉我,它Could not deduce (Integral a) arising from a use of ‘toList’
。我对这个消息的理解是toList
要求它的参数是Integral a => PrimeSet a
类型,但这不一定是这种情况Foldable
实例。
该消息还表示,可能的修复方法是添加Integral a
到我的类型签名的上下文foldMap
实现,但是当然我被告知我不允许为类方法提供我自己的类型定义,除非我使用InstanceSigs
,所以我尝试了,但这似乎也不起作用。
所以我的问题是:如果我正在为其编写类实例的类型的类型参数被隐藏,是否可以向类实例添加类型约束 - 或者,重申一下,我可以这样做吗?
instance (Integral a) => Foldable (PrimeSet a) where
(这当然行不通,因为PrimeSet a
有那种*
然而Foldable
需要* -> *
)
不,这是不可能的。高等类型的全部要点是努力工作any参数类型。然而PrimeSet
根本不是真正的参数化——基本上,它是always PrimeSet Integer
。为什么你有那个a
参数根本?
然而,对于“有点容器”的类型有一个不同的类,但不适用于任意类型:单可遍历 http://hackage.haskell.org/package/mono-traversable,或者实际上单折叠 http://hackage.haskell.org/package/mono-traversable-1.0.11.0/docs/Data-MonoTraversable.html#t:MonoFoldable在这种情况下。
{-# LANGUAGE FlexibleInstances, TypeFamilies #-}
import Data.MonoTraversable
type instance Element (PrimeSet a) = a
-- or, if `PrimeSet` is not parameterised,
-- type instance Element PrimeSet = Integer
instance (Integral a) => MonoFoldable (PrimeSet a) where
otoList = YourImplementation.toList
An alternative would be that you do use parameterised types, functors in fact, but not in the normal Hask category of all Haskell types but only in the subcategory whose types areis Integer
. I have such a class in my constrained-categories package http://hackage.haskell.org/package/constrained-categories-0.3.1.1/docs/Data-Foldable-Constrained.html. But, especially for this type you have, this really doesn't seem to make any sense.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)