Haskell Typeclass для кортежей
Я играл со стилистами и делал это:
class Firstable f where
fst :: f a -> a
class Secondable f where
snd :: f a -> a
Затем я попытался добавить реализацию для (,) и понял, что могу сделать:
instance Secondable ((,) a) where
snd (x,y) = y
Я уверен, что это работает, потому что Secondable должен иметь вид (* → *), где ((,) a) имеет этот тип, однако я не знаю, как реализовать Initialable for ((,) * a ) где * - связанная переменная. В моей интерпретации я пытаюсь сделать эквивалент:
instance Firstable (flip (,) a) where ...
Есть ли способ сделать это в Haskell? Предпочтительно без расширений?
Спасибо!
Ответы
Ответ 1
Версия с худшими параметрическими гарантиями может быть выполнена с помощью MPTCS и Fundeps или с TypeFamilies.
type family Fst p
type instance Fst (a,b) = a
type instance Fst (a,b,c) = a
...
class First p where
fst :: p -> Fst p
instance Fst (a,b) where
fst (a,_) = a
instance Fst (a,b,c) where
fst (a,_,_) = a
...
но в конечном итоге вам нужно будет использовать некоторые расширения.
Ответ 2
Вы можете использовать семейства типов, подобные этому (другой подход к тому, что написал Эдвард):
{-# LANGUAGE TypeFamilies #-}
class Firstable a where
type First a :: *
fst :: a -> First a
class Secondable a where
type Second a :: *
snd :: a -> Second a
instance Firstable (a,b) where
type First (a, b) = a
fst (x, _) = x
instance Secondable (a,b) where
type Second (a, b) = b
snd (_, y) = y
Ответ 3
class Firstable f where
fst :: f a b -> a
class Secondable f where
snd :: f a b -> b