В Haskell, как сделать оператор case для динамического TypeRef - PullRequest
2 голосов
/ 10 сентября 2011

Я попробовал следующее:

intType =  typeOf (5::Int)
stringType = typeOf "s"

dynFunc :: Dynamic -> IO ()
dynFunc d =
  case dynTypeRep d of
    stringType -> polyFunc ((fromDyn d "") :: String)
    intType -> polyFunc ((fromDyn d 0) :: Int)
    _      -> error "Could not coerce dynamic value"

Но он предупреждает о совпадении совпадений с шаблоном и работает неправильно.Это всегда идет к первому образцу вместо правильного.

1 Ответ

9 голосов
/ 10 сентября 2011

Левые части -> в выражении case являются шаблонами , а не выражениями .Шаблон stringType будет соответствовать чему угодно и привязывать к нему локальное имя stringType. не сравнивается на равенство.

Компилятор сообщает вам, что ваши шаблоны intType и _ никогда не будут достигнуты;Поскольку шаблон stringType стоит первым и соответствует чему-либо, всегда будет выбрана его правая сторона.

Как предположил Клавдиу, вы захотите использовать охрану.Нечто подобное должно сработать:

dynFunc d | rep == stringType = ...
          | rep == intType    = ...
          | otherwise         = error ...
          where rep = dynTypeRep d

Если у вас много возможностей, вы можете рассмотреть возможность составления списка и использования функции lookup.

...