2015-08-25 2 views
6

Я изучаю тип Семьи и пытаюсь понять, почему я не получаю ошибку времени компиляции в конкретном случае.Общие сведения о типах семейств

Мой тип семьи определяется следующим образом:

type family Typ a b :: Constraint 
type instance Typ (Label x) (Label y) =() 

У меня есть две функции, как показано ниже:

func1 :: (Typ (Label "la") (Label "lb")) => Label "la" -> Label "lb" -> String 
func1 = undefined 

func2 :: (Typ (Label "la") String) => Label "la" -> String -> String 
func2 = undefined 

Обе эти функции компиляции OK.

Когда я пытаюсь просмотреть тип func1, я получаю правильную подпись. Но, когда я пытаюсь посмотреть тип func2, я получаю сообщение об ошибке следующее сообщение об ошибке

Не удалось вывести (Typ (Ярлык «ла») Строка)

Почему это так? Может ли кто-нибудь помочь мне понять?

+0

Мое предположение состоит в том, что это потому, что существует экземпляр, объявленный для 'Typ (Label x) (Label y)', но не для 'Typ (Label x) String'. Каково определение «Лейбл»? – ryachza

+0

'data Label (l :: Symbol) = Get' Я надеялся получить ошибку времени компиляции для' func2', а не ошибку времени выполнения –

+3

Возможно, вас заинтересует [это обсуждение сокращения контекста] (https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-910004.5.3). Я испытываю соблазн назвать это ошибкой, которую жалуется ghci: вероятно, это не должно приводить к уменьшению контекста для пользовательских подписей типа. Обратите внимание, что, конечно, если вы когда-либо пытались использовать 'func2' в реальной программе, которая в конечном итоге вернулась бы к« main », которая не имеет никакого контекста, и, в частности, не будет разрешено иметь« Typ (Label «la»)) String' в его контексте - вы получите ошибку типа. –

ответ

3

я был в состоянии дублировать то, что вы описали с этим определением Label:

import GHC.TypeLits (Symbol) 

data Label (a :: Symbol) 

И добавив:

type instance Typ (Label x) String =() 

Тогда предоставляет тип func2

Edit

Извините, я неправильно понял беспокойство. Я понимаю, что проверка выполнимости ограничения будет отложена до тех пор, пока func2 не будет использоваться, поскольку экземпляр может быть добавлен позже.

Например, добавив:

func3 = func2 (undefined :: Label "la") "" 

причины его неисправности во время компиляции.

Как я понять это в том, что func2 говорит, если вы дадите мне Label "la" и Stringи экземпляр Typ (Label "la") String находится в области видимости во время, я дам вам String. Но func2 не нужно иметь экземпляр в области, чтобы знать , что бы он сделал с одним, если бы он был.

+0

Да @ Даниэль Вагнер. Ваше понимание верное. Меня интересует, почему ошибка типа задерживается. –

+3

@PrasannaKRao «Почему это задерживается» - эта часть проста. Общим принципом является то, что жалобы на неудовлетворенные ограничения задерживаются как можно дольше, для поддержки отдельной компиляции. (С отдельной компиляцией вы можете не знать всех способов удовлетворить ограничение.) Но я не уверен в части «и не дальше». –

+0

@PrasannaKRao Извините, что я неправильно понял и обновил свой ответ. – ryachza

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