重叠实例——不清楚Haskell选择了哪个实例
我有以下使用重叠实例的Haskell代码;我尝试实现一个函数,该函数将函数的类型生成为字符串,或者——更一般地说——对不同的函数类型执行不同的操作:重叠实例——不清楚Haskell选择了哪个实例,haskell,typeclass,Haskell,Typeclass,我有以下使用重叠实例的Haskell代码;我尝试实现一个函数,该函数将函数的类型生成为字符串,或者——更一般地说——对不同的函数类型执行不同的操作: {-# OPTIONS_GHC -fglasgow-exts #-} {-# LANGUAGE OverlappingInstances, IncoherentInstances #-} module Test where data TypeString = MKTS String instance Show TypeString wher
{-# OPTIONS_GHC -fglasgow-exts #-}
{-# LANGUAGE OverlappingInstances, IncoherentInstances #-}
module Test
where
data TypeString = MKTS String
instance Show TypeString where
show (MKTS s) = s
class ShowType b c where
theType :: (b -> c) -> TypeString
instance ShowType b b where
theType _ = MKTS "b -> b"
instance ShowType b c where
theType _ = MKTS "b -> c"
instance ShowType (b, b') c where
theType _ = MKTS "(b, b') -> c"
class Problem a where
showProblem :: a -> TypeString
instance Problem (b -> c) where
showProblem f = theType f
Haskell显示了我键入时的预期行为
> theType (uncurry (+))
(b,b') -> c
但是:有人能解释一下吗
> showProblem (uncurry (+))
b -> c
。。。并解释,如何避免Haskell选择太一般的实例的情况…所使用的
问题的实例是为b->c
制作的。如果查看showProblem
的签名,您将看到没有ShowType
上下文。如果没有上下文,编译器只能静态地推断实例。因此,选择了b->c
的实例,因为它是静态适合的实例
我不知道如何解决这个问题,我想手工提供上下文是可行的,但我真的不知道:
class Problem a where
showProblem :: ShowType a => a -> TypeString
instance Problem (b -> c) where
showProblem :: ShoType (b -> c) => (b -> c) -> TypeString
showProblem = theType
对我来说,使用OverlappingInstances通常意味着我在代码中做出了错误的设计决策。我阅读了Haskell wiki中关于OverlappingInstances的内容。它说它有时有用,但我可以想象一个例子。@fuzzxk:。。。您提到,使用重叠意味着错误的决策;但是,整个数据、可键入模块和整个废弃样板文件不是基于重叠的实例吗?