此
newtype ( Show a , Show b , Show c ) => T a b c = T Int
t :: T a b c -> a -> b -> c -> String
t ( T x ) a b c = show a ++ show b ++ show c
给了我一个错误:
No instance for (Show c)
arising from a use of `show'
In the second argument of `(++)', namely `show c'
In the second argument of `(++)', namely `show b ++ show c'
In the expression: show a ++ show b ++ show c
但是这个
newtype ( Show a , Show b , Show c ) => T a b c = T Int
t :: ( Show a , Show b , Show c ) => T a b c -> a -> b -> c -> String
t ( T x ) a b c = show a ++ show b ++ show c
编译。
为什么?
在第一种情况下,“T a b c”是否已经暗示“(显示a,显示b,显示c)”?为什么有必要明确指定约束?
答案 0 :(得分:11)
不,在数据(newtype)定义上放置上下文从来没有像人们预期的那样完成。它只在构造值时更改构造函数的类型,在模式匹配时不会发生任何新的情况。这是一个基本无用的功能,它已在最新版本的Haskell中删除。
您期望的是非常合理的,但这不是数据类型上下文的作用。
答案 1 :(得分:10)
@augustss所说的是正确的,但你可以使用GADT实现类似的东西。
{-# LANGUAGE GADTs #-}
data T a b c where
T :: (Show a, Show b, Show c) => Int -> T a b c
t :: T a b c -> a -> b -> c -> String
t (T x) a b c = show a ++ show b ++ show c
然而,在大多数情况下,将约束放在函数上是正确的。