Haskell类型类可以部分实现吗?

Haskell类型类可以部分实现吗?,haskell,types,functor,applicative,Haskell,Types,Functor,Applicative,我想制作一对类型来表示模运算。我制作了它的构造器 {- LANGUAGE GADTs -} data Zn e where Zn :: Integer -> Integer -> Zn Integer 因为我希望能把它和所有的事情都搞定。 所以如果我试着把它变成一个函子实例 我无法从上下文:a~整数推断:b~整数。当然,它不能推断出这一点,因为对于所有a和b,该数据类型没有fmap::a->b->ZNA->ZNB的有意义的概念,但只要a和b是这样的,人们就可以从它们实际构建

我想制作一对类型来表示模运算。我制作了它的构造器

{- LANGUAGE GADTs -}
data Zn e where
    Zn :: Integer -> Integer -> Zn Integer
因为我希望能把它和所有的事情都搞定。 所以如果我试着把它变成一个函子实例

我无法从上下文:a~整数推断:b~整数。当然,它不能推断出这一点,因为对于所有a和b,该数据类型没有fmap::a->b->ZNA->ZNB的有意义的概念,但只要a和b是这样的,人们就可以从它们实际构建Zn实例。我也尝试过使用Zn构造函数,所有方法都需要积分e,但我遇到了类似的问题。在这种情况下,s的类型是a,因此用它构造一个Zn,f n::b失败。在第二种情况下,我可以将s从a转换为整数,然后再转换为b,但这很笨拙。整件事有点笨重。我之所以这么做,是因为我希望能够实现Functor和Applicative,在映射函数后执行mod,这样我就可以实现+作为liftA2+等等。模s应该是类型的一部分,但据我所知,依赖类型在Haskell中不实用

对于某些参数,是否可能只有一个类型具有kind*->*implement Functor?

您正在寻找的。它与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函数或其他什么,以避免人们对它的工作方式做出错误的假设。

你正在寻找的。它与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函数或其他东西,以避免人们对它的工作原理做出错误的假设。

我认为这至少在道德上是合法的。就我所见,唯一被打破的法则是omap id=id,它失败了,例如对于Zn 2 10,因为10应该是0。如果我们把价值考虑到等价,我认为它应该是合法的。设fx=x`mod`8;gx=x*6;m=Zn9.4。现在omap f omap g m是6,但是omap f。gm是0。@chi尽管如此,我觉得这在道德上是合法的。我同意。这太多了。有趣的是,MonoTraversable库不包含MonoApplication,因此可以添加该类,但现在我只使用modMap和modLift2。无论如何,应用是有问题的,因为pure不知道模数。我认为这至少在道德上是合法的。就我所见,唯一被打破的法则是omap id=id,它失败了,例如对于Zn 2 10,因为10应该是0。如果我们把价值考虑到等价,我认为它应该是合法的。设fx=x`mod`8;gx=x*6;m=Zn9.4。现在omap f omap g m是6,但是omap f。gm是0。@chi尽管如此,我觉得这在道德上是合法的。我同意。这太多了。有趣的是,MonoTraversable库不包含MonoApplication,因此可以添加该类,但现在我只使用modMap和modLift2。Applicative是有问题的,因为pure不知道模数。如果你想把这个类型变成一个数字,我想你的s应该是类型级别的。否则,有人可能会给你ZN32+ZN87,然后你会返回什么?在类型中有s是理想的,但我认为将其作为运行时错误比使用Nat技巧在类型中编码数字要好。如果Haskell对依赖类型有更直接的支持,我会把模数放在类型中。如果你想把这个类型变成一个数字,我认为你的s需要在类型级别上。否则,有人可能会给你ZN32+ZN87,然后你会返回什么?在类型中有s是理想的,但我认为将其作为运行时错误比使用Nat技巧在类型中编码数字要好。如果Haskell对依赖类型有更直接的支持,我会把模数放在类型中。