Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 如何重写typeclass实例_Haskell_Typeclass - Fatal编程技术网

Haskell 如何重写typeclass实例

Haskell 如何重写typeclass实例,haskell,typeclass,Haskell,Typeclass,我想在我的代码中表示上界的概念,因此我创建了一个有区别的联合: data UpperBound a=UpperBound a | DoNotCare派生(Eq、Read、Show) 然后,我手动派生了几个有用的typeclass实例(用于学习): 实例函子上限,其中 fmap_uudonotcare=DoNotCare fmap f(上界x)=上界$f x 实例应用程序上限,其中 纯=上限 DoNotCare _DoNotCare=DoNotCare (上界f)(上界x)=上界$f x 实例可

我想在我的代码中表示上界的概念,因此我创建了一个有区别的联合:

data UpperBound a=UpperBound a | DoNotCare派生(Eq、Read、Show)
然后,我手动派生了几个有用的typeclass实例(用于学习):

实例函子上限,其中
fmap_uudonotcare=DoNotCare
fmap f(上界x)=上界$f x
实例应用程序上限,其中
纯=上限
DoNotCare
_DoNotCare=DoNotCare
(上界f)(上界x)=上界$f x
实例可折叠上限,其中
foldr us DoNotCare=s
foldr fs(上界x)=f x s
实例可遍历上限,其中
traverse u-DoNotCare=纯DoNotCare
遍历f(上界x)=fmap上界$f x
实例可选上限,其中
空=不在乎
DoNotCare x=x
x不关心=x
x ux=x
实例Monad上限,其中
返回=纯
不关心>>==不关心
(上限x)>>=f=f x
实例MonadPlus上限,其中
mzero=空
mplus=()
和一个单一的实用功能:

isWithinBound::Ord a=>a->上限a->Bool
isWithinBound uDonotCare=True
isWithinBound x(上界b)=x
上界x
Nothing
->
DoNotCare
),因此我显然有不必要的重复


我怎样才能以某种方式“包装”一个
Maybe
并将typeclass实例实现重定向到该实例,同时仍然公开
isWithinBound
函数?

最简单的方法是使用
newtype
GeneralizedNewtypeDeriving
扩展,如下所示:

{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveTraversable #-}
module UpperBound (UpperBound, isWithinBound) where

import Control.Monad
import Control.Applicative

newtype UpperBound a = UpperBound { unUpperBound :: Maybe a }
  deriving (Functor, Applicative, Foldable, Traversable, Alternative, Monad, MonadPlus)

isWithinBound :: Ord a => a -> UpperBound a -> Bool
isWithinBound x = maybe True ((<=) x) . unUpperBound
{-#语言泛化newtypedering,DeriveTraversable#-}
模块上限(上限,isWithinBound),其中
进口管制
导入控制
newtype UpperBound a=上限{unUpperBound::可能是a}
派生(函子、应用程序、可折叠、可遍历、可选、单子、单子)
isWithinBound::Ord a=>a->上限a->Bool

isWithinBound x=可能是真的((我不完全确定我是否理解这个问题-但是如果实例实际上是相同的(看起来是一样的),您不能只使用
newtype
?或者甚至使用类型同义词吗).关于
isWithinBound
,重写很简单,因此需要一个
也许是一个
,而不是您的自定义版本。@RobinZigmond我的意思是,我仍然希望将案例公开为
上限/DoNotCare
,但在内部将实例声明转发到
也许是
实现。这可能吗?“typeclass实例看起来几乎和那些for Maybe的实例一样”这个“几乎”部分从哪里来?我觉得
Alternative
实例看起来很粗略。它应该是每个包含类型的幺半群(以
empty
为单位,以
为操作)--特别是它应该有
空x=x空=x
,而你的没有。我从来没有意识到
泛化的newtypedering
可遍历的
不起作用(除了
Functor
应用的
Monad
之外,我从来没有使用过它)。我很好奇为什么会这样。@RobinZogmond如果newtype ux=U(tx)和Traversable T,那么traverse返回一个f(tx),其中需要一个f(ux).GHC希望在两者之间实现零成本强制,但实际上没有。您需要fmap U,GHC自己不会这么做。现在,由于函子f,从道德上讲f应该始终是role f representational类型,并且应该有一个可用的强制,但1)Traversable对它没有约束2)存在一些“中断”但是,违反这一规则的有用函子3)GND可能无法使用这些信息,即使这些信息是给定的,4)这些约束是一个非常新的GHC扩展。