为什么String不能在约束中使用?

v0d*_*1ch 2 haskell

为什么我不能设置String约束,但一个Num工作正常?

这有效:

ltest' :: (Num a) => a -> a
ltest' a = (\b -> b * 2) a
Run Code Online (Sandbox Code Playgroud)

这不是:

test' :: (String a) => a -> a
test' a = a ++ " good job"
Run Code Online (Sandbox Code Playgroud)

错误:

• Expecting one fewer argument to ‘String’
  Expected kind ‘* -> Constraint’, but ‘String’ has kind ‘*’
• In the type signature:
    test' :: (String a) => a -> a
Run Code Online (Sandbox Code Playgroud)

Chr*_*tin 13

String 是一种类型:

type String = [Char]
Run Code Online (Sandbox Code Playgroud)

Num 是一个类:

class Num a where
    (+), (-), (*)       :: a -> a -> a
    negate              :: a -> a
    abs                 :: a -> a
    signum              :: a -> a
    fromInteger         :: Integer -> a
    negate x            = 0 - x
Run Code Online (Sandbox Code Playgroud)

约束只涉及类,而不是类型.

ltest'有一个类型参数,a.1这可以明确表达:

ltest' :: forall a. (Num a) => a -> a
Run Code Online (Sandbox Code Playgroud)

这意味着它适用于a具有Num该类实例的任何类型.

test'不需要类型参数,因为它只适用于一种类型2(参数只能是类型String).因此它也不需要任何约束,因为没有要约束的类型参数.

test' :: String -> String
test' a = a ++ " good job"
Run Code Online (Sandbox Code Playgroud)

1换句话说,ltest'具有多态类型.

2换句话说,test'有一个单形类型.