почему в Haskell нет разнородных списков - PullRequest
4 голосов
/ 05 января 2011

Я не понимаю, почему я не могу создать список, который выглядит как [1,"1",1.1] в haskell. Я не думаю, что мешает статическая типизация, потому что я думал, что head теперь будет иметь плохо определенный тип, но потом я подумал об этом, и нет причины, по которой система времени выполнения не создает иную версию head всякий раз, когда в него подается список, поэтому head [1,"1",1.1] будет набираться как List->Int, а head (tail [1,"1",1.1]) будет печататься как List->String. Поскольку во время выполнения уже ведется большая бухгалтерия, почему она не предоставляет более причудливые полиморфные (или общие) версии различных функций прелюдии? Что мне здесь не хватает?

Ответы [ 5 ]

16 голосов
/ 05 января 2011

Это действительно печатание, которое предотвращает это. Рассмотрим определение списка (обратите внимание на параметр типа a, который отсутствует в ваших типах):

data List a = Nil | Cons a (List a)

В Cons a (List a) вы можете видеть, что тип вещи в начале списка должен быть того же типа, что и элементы, которые следуют за ним. Чтобы ответить на ваш вопрос, вы не пропустите много: как вы говорите, среда выполнения могла бы это сделать, но в Haskell вы хотите принимать эти решения при вводе во время компиляции, а не во время выполнения.

Если вам нужны гетерогенные списки, вы можете увидеть волшебство Олега Киселева в его работе над HList (= Гетерогенный список). Это может быть не совсем то, что вы хотите, но в том же приблизительном направлении.

3 голосов
/ 06 января 2011

Посмотрите на Гетерогенные коллекции

{-# 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 ()"]

-}
3 голосов
/ 05 января 2011

Существует гетерогенный тип списка, называемый 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)]

Во многих случаях у ваших данных есть тип, который вам просто нужно найти.

3 голосов
/ 05 января 2011

Точно так же, как вы знаете, на самом деле существует пакет для разнородных списков, использующий нетривиальные приемы, и вам действительно следует убедиться, что вы хорошо понимаете систему типов, прежде чем углубляться в это.У вас нет этого по умолчанию из-за системы типов.Список в Хаскеле - это не просто список.Это список , где a - Int, String, все, что вы хотите.НО, один список может содержать только один тип значений.

Обратите внимание, что вы можете определять "гетерогенные списки" элементов, удовлетворяющих некоторым ограничениям, используя экзистенциальную квантификацию, но я думаю, что вы еще не там и действительно должны сосредоточитьсяпонимание других ответов здесь, прежде чем идти дальше.

3 голосов
/ 05 января 2011

Потому что в Haskell все типы известны во время компиляции. Нет такой вещи, как ожидание времени выполнения, чтобы увидеть, какой будет тип. И поскольку этого достаточно для того, чтобы делать все, что вам захочется, в динамически типизированной системе, и в то же время легче подумать о загрузке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...