2016-08-17 2 views
3

Я работаю через haskell book, и я понял, что :sprint x используется для печати элементов x, был оценен, а элементы не были (те, которые не выражены по «_»).Понимание того, как: спринт и оценка оценки работает в haskell

Одним из примеров, приведенных в книге,

Prelude> let blah = enumFromTo 'a' 'z' 
Prelude> :sprint blah 
blah = _ 

Prelude> take 1 blah 
"a" 
Prelude> :sprint blah 
blah = 'a' : _ 

Чтобы проверить с другим входом я сделал это в GHCi: -

prelude> let b = [1,2,3,4,5] 
prelude> :sprint b 
b = _ 
prelude> take 1 b 
[1] 
prelude> :sprint b 
b = _ 

В случае, если не выход :sprint b в последнем команда b = 1 : _, так как мы оцениваем только один элемент списка и оператор cons при использовании команды take 1 b ?? Но он показывает результат выше. Как и почему это происходит? Не должен ли выход быть похожим на вывод типа String?

Edit: Я экспериментировал больше и получил этот результат: -

prelude> let b = [1..10] :: [Int] 
prelude> :sprint b 
b = _ 
prelude> take 3 b 
[1,2,3] 
prelude> :sprint b 
b = 1 : 2 : 3 : _ 

Хорошо, мое первоначальное предположение, что это из-за того, как я Построив два списка? Один из них использует диапазоны, а другой - путем явного указания его элементов (который по очереди создает список, используя рекурсивные конструкторы cons: :, регенерирующие его элементы)

ответ

6

Поведение :sprint может показаться немного сложным. В этом случае обратите внимание на тип x:

> :t x 
x :: Num t => [t] 

Потому что полиморфные, фактические значения, которые получают, полученные в зависимости от конкретного экземпляра Num, что вам требуется. Таким образом, x ведет себя скорее как функция, которая будет создавать список [1,2,3,4,5], когда он сможет определить, какой тип вы хотите, чтобы элементы имели.

Теперь вы можете подумать, «хорошо, я сделаю список, который не полиморфный», так что вы пытаетесь это:

> let x = [1,2,3,4,5 :: Int] 
> :t x 
x :: [Int] 
> :sprint x 
x = [1,2,3,4,5] 

Какого черта? Если вы думаете об этом, это имеет смысл. Мы ясно сказали ghci, что такое список. Это не похоже на то, что он может ее не оценить, а затем переоценить позже. (Это было бы расточительно в любом случае.) Но давайте посмотрим, что происходит, когда мы пытаемся сопоставить функции по х:

> let y = map (+1) x 
> :sprint y 
y = _ 
> take 1 y 
[2] 
> :sprint y 
y = 2 : _ 

Так же, как и ожидалось!

Надеюсь, что это поможет. Ленькая оценка - одна из самых сложных вещей о Haskell (когда это становится важным).

+2

Возможно, стоит добавить, что первая проблема исчезнет, ​​если вы выполните ': set -XMonomorphismRestriction'. Некоторые примеры использования ': sprint', например. в * Parallel и Concurrent Haskell *, предшествующее использованию по умолчанию '-XNoMonomorphismRestriction' внутри ghci, и поэтому порождают эту проблему. Вы должны, вероятно, всегда отключать его или быть безжалостным с подписями, прежде чем возиться с ': sprint' – Michael

+0

должным образом. Спасибо за совет. –

Смежные вопросы