2010-06-08 3 views
6

Почему Haskell не может решить проблему [[]] (список списков)?
Почему это не просто * -> *, так как я могу дать ему такой тип, как Int, и получить [[Int]], который имеет вид *.Почему GHCi не может решить проблему [[]]?

+4

Это похоже на вопрос, почему GHC не может определить тип значения 'sqr t sqrt', хотя 'sqrt' сам является' Double -> Double' – newacct

+1

: t sqrt sqrt отлично работает в GHCI, хотя – Squidly

+8

Это потому, что 'sqrt' является полиморфным. Лучшая аналогия: нет. – sdcvvc

ответ

8

Я думаю, что это так же, как с Maybe Maybe, хотя в последнем случае причина, пожалуй, яснее: конструктор типа «внешний» ожидает передачи типа доброго *, но видит конструктор типа типа * -> * («внутренний» Maybe/[]) и жалуется. Если я прав, это не проблема с функциональностью GHCi :kind, а с поиском правильного синтаксиса для выражения композиции конструкторов более высокого типа.

В качестве временного решения, что-то вроде

:kind forall a. [[a]] 
:kind forall a. Maybe (Maybe a) 

можно использовать (с соответствующим расширением языка включен - ExistentialQuantification, я думаю, - для того, чтобы синтаксис forall).

+1

Эта статья из Haskell Café может быть актуальной: http://www.mail-archive.com/[email protected]/msg08530.html - Состав конструкторов типов. –

+0

Я не думаю, что был создан экзистенциальный тип (который является '*'). Простым способом, но вне GHCi, является 'type a = [[a]]' (который является '* -> *'). – sdcvvc

+1

@sdcvvc - это универсально квантифицированный полиморфный тип (не экзистенциальный). –

4

Если мы desugar [[]] как [] [], тогда очевидно, что он плохо созрел, потому что [] :: * -> *.

Если вам действительно нужен «список списков», вам нужно написать два типа конструкторов вида * -> *. Вы не можете сделать это без небольшого шаблона, потому что у Haskell нет лямбда уровня. Вы можете сделать это, хотя:

newtype Comp f g a = Comp { unComp :: f (g a) } 

Теперь вы можете написать:

type ListList = Comp [] [] 

И писать функции, используя его:

f :: ListList Int -> ListList Int 
f = Comp . map (map (+1)) . unComp 

Functor композиции, как это имеет применение в нескольких областях, в частности, Swierstra-ые годы "Data types a la carte"

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