不清楚Haskell选择了哪个实例

我有以下使用重叠实例的Haskell代码; 我尝试实现一个将函数的类型作为String来生成的函数,或者 - 更一般地说 - 对不同的函数类型做不同的事情:

{-# 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选择一个过于普通的实例的情况......


使用的Problem的实例是为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通常意味着我在代码中做了错误的设计决定。

链接地址: http://www.djcxy.com/p/43519.html

上一篇: not clear which instance is chosen by Haskell

下一篇: polymorphic instances for typeclasses in Mercury language