2017-06-28 16 views
7

私はF#を勉強していて、this tutorialのようなパーサーコンビネータを実装しようとしています。提案されたソリューションの一部をコピー&ペーストした後、自分でカスタマイズしようとしました。F#一致する式と 'as'パターン

確かに私が見逃したことがありますが、コンパイラは私に奇妙なエラーメッセージを表示します。

type T<'a> = 
    | A of string 
    | B of 'a 

let foo a b = 
    match a with 
    | A s as x -> x 
    | B i -> 
     match b with 
     | A s as x -> x 
     | B j -> 
      B (i, j) 

上記のコードで私が見つけた問題の一般化:エラーは最後の結果に通知された(最も内側のマッチング式のB支店):

error FS0001: Type mismatch. Expecting a 
    'a 
but given a 
    'a * 'b 
The resulting type would be infinite when unifying ''a' and ''a * 'b' 

しかし、私はドンが」その後、コンパイラは再び幸せです

let foo a b = 
    match a with 
    | A s -> A s // it can also be '| A s as x -> A s' 
    | B i -> 
     match b with 
     | A s -> A s 
     | B j -> 
      B (i, j) 

:tはasパターンを使用します。

なぜ私は同じ論理の結果が既に存在する場合はそれを再作成する必要はありません。

A s as x -> x 

x

答えて

7

fooに必要な戻り型がT<('a * 'a)>いる間T<'a>を入力しています。 Aのケースには'aの値が含まれていませんが、forall 'a . T<'a>のような多型がありません。 2番目の例では、必要な型を持つことができるAという新しいインスタンスを作成しています。

+0

私は間違いを理解しています: 'A'は型自体ではなく' T'型のコンストラクタなので、 'x'は' T <'a * 'b> '型ではありません。ありがとう! – Atropo

関連する問題