(以下の場合は、怠惰や多型の値
class Show a where show :: a -> String
class Read a where read :: String -> a
にShow
とRead
を簡素化し、read
が失敗したことがないことを前提としています。)
それは1フォームの実存種類を作ることができることはよく知られているのです
data ShowVal where
ShowVal :: forall a. Show a => a -> ShowVal
そして、このような
などの "異種のリスト":: [ShowVal]
を構築
l = [ShowVal 4, ShowVal 'Q', ShowVal True]
また、代わりに、1は 直後のすべて(リスト:: [String]
、正確に同型であるような
l = [show 4, show 'Q', show True]
を構築することができるので、これは、唯一のものは比較的無用であることはよく知られています1つは、 ShowVal
はshow
です)とすることができます。リスト内の各値に対して、show
の 結果を自動的にメモ化されるので、何String
が使用されない以上 回(及びString
sはで計算されていない計算されないので
怠惰は、これは特にいいせるすべて)。
ShowVal
関数がShow
辞書実存タプルexists a. (a -> String, a)
、 と等価です。
同様の構築物がRead
のために行うことができます:read
たちは本当にそれを必要としないことを意味している(ReadVal
が ユニバーサルいうより実存で、その戻り値で多型であるため、
data ReadVal where
ReadVal :: (forall a. Read a => a) -> ReadVal
なお、 で、ハスケルにはファーストクラスのユニバーサルがありますが、 にはShow
と似ています。
我々はまた、リスト:: [ReadVal]
行うことができます:ちょうどShow
と同様
l = [ReadVal (read "4"), ReadVal (read "'Q'"), ReadVal (read "True")]
を、リスト:: [ReadVal]
は(我々は常に取得することができ、そのよう
l = ["4", "'Q'", "True"]
として リスト:: [String]
と同型であります元String
戻ると
newtype Foo = Foo String
instance Read Foo where read = Foo
Read
型クラスが開いているため。)
ReadVal
forall a. (String -> a) -> a
(CPSスタイルの表現)ユニバーサル関数と等価です。ここでRead
ディクショナリは、戻り値が引数ではなく多形であるため、 ReadVal
のプロデューサではなく、プロデューサによって提供されます。
ただし、これらの表現のどちらでもString
の表記Show
で取得する自動 のメモを取得していません。私たちのタイプの read
は高価な演算ですので、同じタイプの同じString
に を計算したくないとしましょう。
我々はクローズタイプを持っていた場合、我々のような何かを行うことができます:
data ReadVal = ReadVal { asInt :: Int, asChar :: Char, asBool :: Bool }
をそしてそれらの線に沿って
ReadVal { asInt = read s, asChar = read s, asBool = read s }
か何か値を使用します。
この場合、ReadVal
を1つのタイプとして使用した場合でも、値が使用されるたびに String
が解析されます。簡単な方法は ReadVal
多形を維持しながらメモを取得するにはありますか? GHCは自動的にそれを行うために取得
は(、それは何とか可能だ場合も同様Show
場合に、 理想的であるより明示的なメモ化のアプローチ - 。 おそらくTypeable
制約を加えることで - ?もOKでしょう。 )
あなたの 'ReadVal'コードは意味を持ちません。 'ReadVal" 4 "'は整数 "4"と何か関係があるかのように書きます。代わりに 'ReadVal 4'について議論してみませんか? 'ReadVal 4 'が可能であることを理解すれば、' [ReadVal] 'は' [String] 'と同型ではないことが明らかになります。 –
あなたはそうです - 私は 'ReadVal(read" 4 ")'を意味しました。私は掲示する前にタイプチェックをしておくべきです...それを反映するために質問を更新します、ありがとう。 ( 'ReadVal'の引数は' Num'よりも多相でなければならないので、 'ReadVal 4'も有効ではありません) – shachaf
私は' data ReadVal = forall aのような定義を覚えていました。 a => ReadVal a'を読み、GADTはありません。この定義で 'ReadVal 4 'が可能です。私はあなたの定義をより詳細に見てきました。私はそれを全く理解していないと認めます。 –