Функциональная зависимость в Haskell

Я не могу этого понять. Зачем он нам вообще нужен? Я имею в виду, что если я использую параметр одного типа, я думаю, это означает, что они должны быть одного типа.

Я слышал, что это может помочь компилятору избежать бесконечного цикла. Может ли кто-нибудь рассказать мне об этом подробнее?

В конце концов, есть ли какие-то «шаблоны и практики», которым мы должны следовать при использовании функциональной зависимости в реальном мире Haskell?

[Дополнительный вопрос]

class Extract container element where
  extract :: container -> element

instance Extract (a,b) a where
  extract (x,_) = x

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

Но когда я попробовал этот код в GHCi, я получил следующие отзывы:

*Main> extract('x',3)
<interactive>:1:0:
    No instance for (Extract (Char, t) element)
      arising from a use of `extract' at <interactive>:1:0-13
    Possible fix:
      add an instance declaration for (Extract (Char, t) element)
    In the expression: extract ('x', 3)
    In the definition of `it': it = extract ('x', 3)

Когда один из них был указан как тип «Char», почему другой все еще является неразрешенным «элементом» типа?


person aXqd    schedule 25.11.2010    source источник
comment
поможет ли haskell.org/haskellwiki/Functional_dependencies?   -  person lijie    schedule 25.11.2010


Ответы (1)


Я думал, что это объясняет это довольно хорошо. Таким образом, в основном, если у вас есть отношение FD a -> b, все это означает, что для экземпляра класса типов может быть только один "b" с любым "a", поэтому Int Int, но вы не можете также есть Int Float. Вот что они имеют в виду, когда говорят, что «b» однозначно определяется из «a». Это распространяется на любое количество параметров типа. Причина, по которой это необходимо: 1. Вывод типа 2. Иногда вам нужно такое ограничение.

Альтернативой FD является расширение семейств типов, но не для всех случаев FD.

person snk_kid    schedule 25.11.2010
comment
Спасибо за ваш отзыв. Эта статья великолепна. Теперь я точно знаю, в чем мой настоящий вопрос. Вы сказали: «Иногда вам нужно такое ограничение». Я понимаю эту часть. Но я не понимаю, зачем это нужно для вывода типов. Я обновил свой вопрос другим дополнительным вопросом. Пример взят с той вики-страницы, которую вы упомянули выше. - person aXqd; 26.11.2010
comment
Я наконец-то понял. Компилятор все еще пытается найти правильный экземпляр класса типов, поэтому он пока не имеет ничего общего с этим конкретным экземпляром. Я не даю возвращаемый тип, поэтому он неоднозначен. - person aXqd; 27.11.2010
comment
Если я добавлю функциональную зависимость, компилятор может быть уверен, что пока тип контейнера может найти совпадение, компилятор может использовать этот экземпляр, потому что теперь он может иметь только ОДИН тип возвращаемого типа. - person aXqd; 27.11.2010