【问题标题】:Overlapping instances -- not clear which instance is chosen by Haskell重叠的实例——不清楚 Haskell 选择了哪个实例
【发布时间】:2011-07-05 15:32:19
【问题描述】:

我有以下使用重叠实例的 Haskell 代码;我试图实现一个函数,它将函数的类型生成为字符串,或者——更一般地说——为不同的函数类型做不同的事情:

{-# 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 选择过于笼统的实例的情况...

【问题讨论】:

    标签: haskell typeclass


    【解决方案1】:

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

    【讨论】:

    • 我阅读了有关 OverlappingInstances 的 Haskell wiki。它说它有时很有用,但我可以想象一个例子。
    • @FUZxxk: ...你提到,使用重叠意味着错误的决策决定;但是整个 Data.Typeable 模块和整个 Scrap Your Boilerplate-Stuff 不是基于重叠实例吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2020-04-21
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多