4

私はHaskellとStackoverflowの初心者です。これが私の最初の、そしておそらく非常に基本的なHaskellの質問です。

module M where

import Data.HList

data R r a 

r1 = undefined :: R a Int
r2 = undefined :: R a Double

rPair :: R r a -> R r b -> (R r a, R r b)
rPair = (,)

rp = rPair r1 r2

これは、r1とr2がrでポリモーフィックである場合でも、rPairが型シグネチャに従ってr型を整列させることは理にかなっています。この「アライメント」の専門用語はありますか?

class HList l => RList r l
instance RList r HNil
instance RList r l => RList r (HCons (R r a) l)

rCons :: RList r l => R r a -> l -> (HCons (R r a) l)
rCons = hCons

rc = rCons r1 (rCons r2 hNil)

rConsは、渡されたRがrで単相であり、必要に応じてリストのrタイプを制約する場合にうまく機能します。しかし、それらがrで多形である場合、rPairのように整列せず、エラーが発生します(上記のrcを定義します)。

No instance for (RList r (HCons (R r1 Double) HNil))

なぜそうなるのかについては漠然とした直感がありますが、私の質問は2つの部分に分かれています。誰かがその現象を明確に説明できますか?次のようにrConsを作成するにはどうすればよいですか?

r1 = undefined :: R a Int
r2 = undefined :: R a Double

rc :: HCons (R a Int) (HCons (R a Double) HNil)
rc = rCons r1 (rCons r2 hNil)

ありがとう、_c

4

1 に答える 1

1

2 番目の質問に答えるには、型等価制約 (TypeFamilies 拡張から) を使用してRListインスタンス定義を緩和できます。

class HList l => RList r l
instance RList r HNil
instance (RList r1 l, r1 ~ r2) => RList r1 (HCons (R r2 a) l)

rcこれで、目的のタイプに推論されます。

この現象を「明確に説明」できるとは思いませんが (誰かがきっとそうするでしょう)、 と の違いは明らかですrPairrCons前者はr両方の引数の型を同じ型変数にバインドしますが、後者はそうではありません。 2 番目の引数は、 for thatlのインスタンスが存在する必要があるという制約があります)。の型署名がなく(元の例の型チェックを提供した場合)、r1 と r2 はのインスタンス定義を見つけようとします。RListlrcrRList r (HCons (R r1 Double) HNil)rr1- 2番目から)そうしない。型等価制約を使用して、RList のインスタンスを 2 つの異なるものr1と、これらが等価である必要があるという唯一の条件で定義します。したがって、GHC はforr2のインスタンスを解決するときに、それらを同じ多相型変数にバインドするように見えます。RListl

于 2011-03-05T02:49:45.333 に答える