Haskellのようなリストを作成できない理由がわかりません[1,"1",1.1]
。邪魔になるのは静的型付けではないと思います。なぜなら、それhead
は今では不適切に定義された型を持つと思ったからですhead
。 list が入力されるため、head [1,"1",1.1]
asList->Int
およびas とhead (tail [1,"1",1.1])
入力されList->String
ます。ランタイムはすでに多くの簿記を行っているのに、さまざまなプレリュード関数のより洗練されたポリモーフィック (またはジェネリック) バージョンを提供しないのはなぜですか? ここで何が欠けていますか?
5 に答える
これを防ぐのは確かにタイピングです。a
リストの定義を考えてみましょう (あなたの型から欠落している type parameter に注意してください):
data List a = Nil | Cons a (List a)
リストのCons a (List a)
先頭にあるもののタイプは、それに続く要素と同じタイプでなければならないことがわかります。あなたの質問に答えるために、多くのことを見逃しているわけではありません.ランタイムがそれを行うことができると言っていますが、Haskellでは、ランタイムではなくコンパイル時にこれらの型付けの決定を行う必要があります.
異種リストが必要な場合は、Oleg Kiselyov による HList (= 異種リスト)に関する作業でいくつかの魔法を見ることができます。それはまさにあなたが望むものではないかもしれませんが、大まかな方向性は同じです。
HList(Hackageで入手可能)と呼ばれる異種リストタイプがありますが、リストの内容にはおそらくタイプがあることに注意してください。次のようなことを考えてみてください。
history = [-12, "STATEMENT END", (-244, time January 4 2010), ...]
データには、出現するのに苦労しているタイプがあります。例:
data HistoryEntry = Withdrawal Int | StatementClosing | ScheduledPayment Int CalendarTime
history = [Withdrawal 12, StatementClosing, ScheduledPayment 244 (time January 4 2010)]
多くの場合、データには、検索する必要があるタイプがあります。
Haskell では、すべての型がコンパイル時に認識されるためです。型がどうなるかを見るために実行時まで待つようなことはありません。これは、動的に型付けされたシステムで実行したいことを実行するのに十分であり、起動について簡単に推論できるためです。
ご存知のように、実際には異種リスト用のパッケージがあり、自明ではない手法を使用しています。これに飛び込む前に、型システムを十分に理解していることを確認する必要があります。型システムのため、デフォルトではこれはありません。Haskell のリストは単なるリストではありません。これは a のリストで、'a' は Int、String など、必要なものは何でも構いません。ただし、1 つのリストに含めることができる値のタイプは 1 つだけです。
存在量化を使用して、いくつかの制約を満たす要素の「異種リスト」を定義できることに注意してください。
異種コレクションを見てください
{-# OPTIONS -fglasgow-exts #-}
--
-- An existential type encapsulating types that can be Shown
-- The interface to the type is held in the show method dictionary
--
-- Create your own typeclass for packing up other interfaces
--
data Showable = forall a . Show a => MkShowable a
--
-- And a nice existential builder
--
pack :: Show a => a -> Showable
pack = MkShowable
--
-- A heteoregenous list of Showable values
--
hlist :: [Showable]
hlist = [ pack 3
, pack 'x'
, pack pi
, pack "string"
, pack (Just ()) ]
--
-- The only thing we can do to Showable values is show them
--
main :: IO ()
main = print $ map f hlist
where
f (MkShowable a) = show a
{-
*Main> main
["3","'x'","3.141592653589793","\"string\"","Just ()"]
-}