not clear which instance is chosen by Haskell

I have the following Haskell code using overlapping instances; I tried to implement a function which yield the funcion's type as a String, or -- more generally speaking -- does different things for different function types:

{-# 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 shows the expected behavior when I type

> theType (uncurry (+))
(b,b') -> c

But: Can anyone explain the following:

> showProblem (uncurry (+))
b -> c

... and explain, how to avoid such situations where Haskell chooses a too general instance...


The instance for Problem used is made for b -> c . If you look at the signature of showProblem , you will see that there is no ShowType context. If there is no context, the compiler can only infer the instance statically. Because of this, the instance for b -> c is chosen, as it is the instance that fits statically.

I don't know how to solve this, IMHO it could work to provide the context by hand, but I really don't know:

class Problem a where
  showProblem :: ShowType a => a -> TypeString

instance Problem (b -> c) where
  showProblem :: ShoType (b -> c) => (b -> c) -> TypeString
  showProblem = theType

For me, using OverlappingInstances usually means, that I did a wrong design decision in my code.

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

上一篇: 使用元组时非法实例声明

下一篇: 不清楚Haskell选择了哪个实例