LINUX.ORG.RU

mindfuck

 


0

2
Prelude> :t [1,[2,3],4]
[1,[2,3],4] :: (Num [t], Num t) => [[t]]

Почему так? 1 и [2,3] - это же разные типы. Или я чего-то не понимаю?

P.S. ghc-7.8.3

Сейчас проверил в других версиях. GHC-7.6 выдаёт то же самое. Hugs выдает ошибку, что куда более ожидаемо.

hateyoufeel ★★★★★
() автор топика
Ответ на: комментарий от hateyoufeel

нет, я это у видел у Фуда на поинте, и там же и написал.

тип цифры в ghc это (Num a => a), т.е. любой тип a имеющий констрейнт Num a, а конкретно функцию fromInteger. Поэтому везде где ты видишь цифру ты можешь представить, что там стоит fromInteger цифра.

Соответвенно функция принимает вид [fromIngeger 1,[fromInteger 2,fromInteger 3],fromInteger 4],

очевидно, что её тип это [[t]], но т.к. мы вызываем fromInteger на t, то появляется констрейни Num t, отсюда же констрейн [t]. Если попытаться вычислить данную функцию, то подходящий инстанс не будет найден, но все можно исправить:

Prelude> instance Num t => Num [t] where fromInteger t = [fromInteger t]

<interactive>:4:10: Warning:
    No explicit implementation for
      ‘+’, ‘*’, ‘abs’, ‘signum’, and (either ‘negate’ or ‘-’)
    In the instance declaration for ‘Num [t]’
Prelude> [1,[2,3]]
[[1],[2,3]]

Так понятно?

P.S. на #haskell наверняка получше написали, но мне лень открывать ноут, на котором я там залогинен, чтобы смотреть логи.

qnikst ★★★★★
()
Последнее исправление: qnikst (всего исправлений: 1)
Ответ на: комментарий от qnikst

Тогда почему такое не прокатывает? Я понимаю, что можно подключить FlexibleContexts, но тогда почему первый вариант работает без этого?

Prelude> let x = [1,2] :: (Num [t], Num t) => [t]

<interactive>:16:18:
    Non type-variable argument in the constraint: Num [t]
    (Use FlexibleContexts to permit this)
    In an expression type signature: (Num [t], Num t) => [t]
    In the expression: [1, 2] :: (Num [t], Num t) => [t]
    In an equation for ‘x’: x = [1, 2] :: (Num [t], Num t) => [t]

На #haskell тоже через подобный пример с инстансом объясняли.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от qnikst

То же самое.

Prelude> let x = [1,2] :: (Num [t], Num t) => [[t]]

<interactive>:2:18:
    Non type-variable argument in the constraint: Num [t]
    (Use FlexibleContexts to permit this)
    In an expression type signature: (Num [t], Num t) => [[t]]
    In the expression: [1, 2] :: (Num [t], Num t) => [[t]]
    In an equation for ‘x’: x = [1, 2] :: (Num [t], Num t) => [[t]]

Хотя оригинальный код тоже валится с этой ошибкой, если вручную указать тип.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

потому, что ты явно руками написал :)

Prelude>  let x = [1,[2,3],4] :: (Num [t], Num t) => [[t]]

<interactive>:2:25:
    Non type-variable argument in the constraint: Num [t]
    (Use FlexibleContexts to permit this)

точно так же требует FlexibleContexts, которые разрашеют использовать констрейнты вида (C v t1 t2 ..).

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Да, я тут что-то затупил. Почитал про FlexibleContexts ещё раз, всё ок. Спасибо.

hateyoufeel ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.