Переменная не в области: doubleMe :: [Integer] - > t (Haskell)

Murphy Ho спросил: 28 марта 2018 в 02:16 в: haskell

Я не знаю, что проблема связана с этим. Я просто следовал тому, что говорила книга. Ниже приводится описание книги [learn you a Haskell for Great Good]:

Скажем, у вас есть неизменный список чисел xs = [1,2,3,4,5,6,7 , 8] и функцию doubleMe, которая умножает каждый элемент на 2 и затем возвращает новый список. Если бы мы хотели умножить наш список на 8 на императивном языке и diddoubleMe (doubleMe (doubleMe (xs))), он, вероятно, пройдет через список один раз и сделает копию, а затем вернет ее.


2 ответа

chepner ответил: 28 марта 2018 в 02:38

doubleMe не является встроенной функцией. Книга предполагает , что вы определили это с помощью чего-то вроде

doubleMe = fmap (* 2)

(это то, что означает "скажи, что у вас есть ...".)

Вы еще не определили функцию, поэтому интерпретатор сообщает вам, что doubleMe не определено.

Willem Van Onsem ответил: 28 марта 2018 в 02:45

Книга гласит:

Скажем, у вас есть ...

Это в гипотетическом смысле: оба списка xs и функция doubleMe не существуют как встроенные в Haskell, целью книги является демонстрация того, что если бы у нас была такая функция, существует важное различие между тем, как интерпретатор Haskell создаст новый список (в ленивым образом), и императивный эквивалент сделает это (создаст три полных списка).

Мы можем определить это с помощью:

Prelude> doubleMe = map (2*)
Prelude> xs = [1,2,3,4,5,6,7,8]
Prelude> doubleMe xs
[2,4,6,8,10,12,14,16]

Так что здесь мы определяем как doubleMe, так что мы умножаем все элементы. Вероятно, книга объясняет, что в Haskell, если мы оценим это из-за лени, мы никогда не будем полностью создавать промежуточные списки в случае, если мы вызываем:

 Prelude> doubleMe (doubleMe (doubleMe xs))
[8,16,24,32,40,48,56,64]

Действительно, если мы хотим получить В первом списке мы будем оценивать первый элемент map (2*), и каждый раз он умножается на два, пока мы не получим восемь.