Haskell 类型类可以部分实现吗?
Can Haskell Typeclasses be Partially Implemented?
我想做一个对类型来表示模运算。我做了它的构造函数
{- LANGUAGE GADTs -}
data Zn e where
Zn :: Integer -> Integer -> Zn Integer
因为我希望能够 fmap
处理它和所有事情。
因此,如果我尝试将其设为 Functor
实例
instance Functor Zn where
fmap f (Zn s n) = Zn s $ mod (f n) s
我得到 Could not deduce: b ~ Integer from the context: a ~ Integer
。当然它不能推断出这一点,因为这种数据类型对所有 a
和 b
没有有意义的 fmap :: (a -> b) -> Zn a -> Zn b
概念,但只要 a
和 b
] 是这样的,实际上可以从它们构造 Zn
个实例(即 Integer
)。我还尝试使用 Zn
构造函数,所有方法都需要 Integral e
但我遇到了类似的问题。在这种情况下,s
的类型为 a
,因此用它构造 Zn
而 f n :: b
失败。在第二种情况下,我可以将 s
从 a
转换为 Integer
,然后再转换为 b
,但这很笨拙。整个事情有点笨拙。我这样做是因为我希望能够在映射函数后实现 Functor
和 Applicative
来执行 mod
这样我就可以将 +
实现为 liftA2 (+)
等等。模数 s
应该是类型的一部分,但据我所知,依赖类型在 Haskell 中不实用。
是否可以让种类为 * -> *
的类型仅对某些参数实现 Functor
?
您正在寻找 MonoFunctor
。它就像 Functor
,但使用固定的内部类型而不是参数多态。以下是您如何为您的类型实施它:
{-# LANGUAGE TypeFamilies #-}
import Data.MonoTraversable
data Zn = Zn Integer Integer
type instance Element Zn = Integer
instance MonoFunctor Zn where
omap f (Zn s n) = Zn s $ mod (f n) s
但是,请注意,这种情况并不完全合法。你最好只做一个 modMap
函数或其他东西,以避免人们对它的工作方式做出错误的假设。
我想做一个对类型来表示模运算。我做了它的构造函数
{- LANGUAGE GADTs -}
data Zn e where
Zn :: Integer -> Integer -> Zn Integer
因为我希望能够 fmap
处理它和所有事情。
因此,如果我尝试将其设为 Functor
实例
instance Functor Zn where
fmap f (Zn s n) = Zn s $ mod (f n) s
我得到 Could not deduce: b ~ Integer from the context: a ~ Integer
。当然它不能推断出这一点,因为这种数据类型对所有 a
和 b
没有有意义的 fmap :: (a -> b) -> Zn a -> Zn b
概念,但只要 a
和 b
] 是这样的,实际上可以从它们构造 Zn
个实例(即 Integer
)。我还尝试使用 Zn
构造函数,所有方法都需要 Integral e
但我遇到了类似的问题。在这种情况下,s
的类型为 a
,因此用它构造 Zn
而 f n :: b
失败。在第二种情况下,我可以将 s
从 a
转换为 Integer
,然后再转换为 b
,但这很笨拙。整个事情有点笨拙。我这样做是因为我希望能够在映射函数后实现 Functor
和 Applicative
来执行 mod
这样我就可以将 +
实现为 liftA2 (+)
等等。模数 s
应该是类型的一部分,但据我所知,依赖类型在 Haskell 中不实用。
是否可以让种类为 * -> *
的类型仅对某些参数实现 Functor
?
您正在寻找 MonoFunctor
。它就像 Functor
,但使用固定的内部类型而不是参数多态。以下是您如何为您的类型实施它:
{-# LANGUAGE TypeFamilies #-}
import Data.MonoTraversable
data Zn = Zn Integer Integer
type instance Element Zn = Integer
instance MonoFunctor Zn where
omap f (Zn s n) = Zn s $ mod (f n) s
但是,请注意,这种情况并不完全合法。你最好只做一个 modMap
函数或其他东西,以避免人们对它的工作方式做出错误的假设。