Как указать параметр типа в сопоставлении с образцом для фантомного типа - PullRequest
2 голосов
/ 05 февраля 2011

Допустим, у меня есть это:

data PT1
data PT2
data DT1 a = DT1 { field :: Int }

newtype DT2 a = DT2 (DT1 a)

f :: Int -> DT2 a -> Int
f x (DT2 (DT1 PT1 field)) = 5 -- How do I specify the type param?
f x (DT2 (DT1 PT2 field)) = 7 -- How do I specify the type param?

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

Ответы [ 2 ]

3 голосов
/ 05 февраля 2011

Вы не можете сопоставить образец по типу. Что вы можете сделать, так это использовать класс типов:

class Effable t where
  f :: Int -> t -> Int

instance Effable (DT2 PT1) where
  f x (DT2 _) = 5

instance Effable (DT2 PT2) where
  f x (DT2 _) = 7
0 голосов
/ 06 февраля 2011

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

{-# LANGUAGE GADTs #-}

data PT1
data PT2

data Tag a where
    PT1 :: Tag PT1
    PT2 :: Tag PT2

data DT1 a = DT1 { tag :: Tag a, field :: Int }

newtype DT2 a = DT2 (DT1 a)

f :: Int -> DT2 a -> Int
f x (DT2 (DT1 PT1 field)) = 5
f x (DT2 (DT1 PT2 field)) = 7

Но теперь этот тип больше не является фантомным - вы носите с собой тег времени выполнения.

Я не уверен, какое это имеет преимущество перед тем, что предложил @ sepp2k, или даже если это будет полезно. Он просто дает вам то, о чем вы просили, с небольшим изменением вашего примера кода: -)

...