2016-09-20 21 views
0

どうして私はStringの制約を設定できませんが、Numはうまく動作しますか?制約で文字列を使用できないのはなぜですか?

これは動作します:

ltest' :: (Num a) => a -> a 
ltest' a = (\b -> b * 2) a 

これはしません:

test' :: (String a) => a -> a 
test' a = a ++ " good job" 

エラー:

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

答えて

8

Stringがタイプです:

type String = [Char] 

Numクラスです:

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

制約はクラスだけではなく、型に関連します。

ltest'のタイプパラメータはaです。 これは、明示的に表すことができる。

ltest' :: forall a. (Num a) => a -> a 

これNumクラスのインスタンスを有する任意のタイプaで動作します。

それは一種類のみ(引数が唯一のタイプStringのものとすることができる)で動作しますので、あなたのtest'、型パラメータを必要としません。したがって、拘束する型パラメータがないため、制約も必要ありません。すなわち

test' :: String -> String 
test' a = a ++ " good job" 

ltest'多型タイプを有しています。すなわち

test'単相タイプを有しています。

+0

ありがとうございます!私は、関数のparamとしてCのようにString型の値だけを渡すようにしたかったのです。function x(char a){} – vodich

+0

これは、型を 'String - > String'として宣言することで実現します。 –

+0

このようなことはありません(String a)=> a - > a? – vodich

関連する問題