haskell - можно ли получить доступ к переменным типа из объявления функции экземпляра? - PullRequest
1 голос
/ 12 сентября 2011

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

class A a where foo :: a b
data C a
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

Конечно, вышеупомянутое разрешится без выражения типа scoped, но у меня есть не-игрушечный пример, где я на самом деле хочу это.

edit

пожалуйста попробуйте свой код, прежде чем вставить его в ответ!Выше (ответ Даниэля) приводит к

Test.hs:51:5: Misplaced type signature: foo :: forall b. C b
Failed, modules loaded: none.

Ответы [ 4 ]

3 голосов
/ 12 сентября 2011

Я думаю, что для преодоления проблемы с решением Дэниела, что вам не разрешено предоставлять сигнатуру для функции класса типов, вы можете просто определить функцию верхнего уровня и «переименовать» ее в экземпляре класса типов. В вашем простом примере должно работать следующее:

{-# LANGUAGE ScopedTypeVariables #-}

class A a where 
    foo :: a b

instance A C where
    foo = foo'

foo' :: C b
foo' = undefined :: C b
2 голосов
/ 12 сентября 2011

Хотя реальное решение было бы предпочтительным, можно обойти проблему, используя asTypeOf и добавив фиктивные параметры.Вот пример:

class A a where foo2 :: b -> a b -- added parameter b
data C a
instance A C where
    foo2 x = undefined `asTypeOf` (wrapA x)

wrapA :: A C => a -> C a
wrapA = undefined

foo :: A a => a b
foo = foo2 undefined

Это сработало для моего реального примера.ура!

1 голос
/ 12 сентября 2011

Я думаю, что в объявлении класса

class A a where
    foo :: a b

тип foo действительно

forall b. a b

т.е. foo должен быть своего рода независимым от типа b,Или b на самом деле не является частью класса A.Так что ... я не думаю, что вы должны иметь возможность ссылаться на это?Хотя, возможно, я не понимаю ... может быть, вы могли бы опубликовать пример, где это необходимо?

Если вам нужно сохранить один и тот же тип для более чем одного метода, вы можете использовать класс многопараметрического типа:

class A a b where
    foo :: a b
    bar :: a b
0 голосов
/ 12 сентября 2011
{-# LANGUAGE ScopedTypeVariables #-}
class A a where foo :: a b
instance A C where
    foo :: forall b. C b
    foo = undefined :: C b

Подробнее.

...