这个
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
Run Code Online (Sandbox Code Playgroud)
给我一个错误:
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
Run Code Online (Sandbox Code Playgroud)
但是这个
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
Run Code Online (Sandbox Code Playgroud)
编译.
为什么?
在第一种情况下,"T ab c"是否已经暗示"(显示a,显示b,显示c)"?为什么有必要明确指定约束?
aug*_*tss 11
不,在数据(newtype)定义上放置上下文从来没有像人们期望的那样完成.它只在构造值时更改构造函数的类型,在模式匹配时不会发生任何新的情况.这是一个基本无用的功能,它已在最新版本的Haskell中删除.
您期望的是非常合理的,但这不是数据类型上下文的作用.
ham*_*mar 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
Run Code Online (Sandbox Code Playgroud)
但是,在大多数情况下,将约束放在函数上是正确的.