«сопоставление с образцом» на Typeable типах - PullRequest
3 голосов
/ 04 мая 2011

Предположим, например, что у нас есть следующая структура данных:

data Foo = Bool Bool | Int Int | Double Double

Теперь есть более простой способ сделать это:

foo :: Typeable a => a -> Foo
foo x = maybe (error "i dunno") id $
  liftM Bool   (cast x) `mplus`
  liftM Int    (cast x) `mplus`
  liftM Double (cast x)

Кто-нибудь задумывался о создании синтаксиса для сопоставления с образцом на набираемых типах?

Ответы [ 3 ]

6 голосов
/ 04 мая 2011

Используйте typeOf и охранники:

foo x
    | tx == typeOf "str" = "string"
    | tx == typeOf True  = "bool"
    | otherwise          = "i dunno"
  where tx = typeOf x
4 голосов
/ 05 мая 2011

Здесь вы можете использовать шаблоны вида, они довольно удобное расширение.

{-# LANGUAGE ViewPatterns #-}

import Data.Data

data Foo = Bool Bool | Int Int | Double Double
         deriving (Show)

foo :: Typeable a => a -> Foo
foo (cast -> Just x) = Int x
foo (cast -> Just x) = Bool x
foo (cast -> Just x) = Double x
foo _ = error "i dunno"

Результаты:

*Main> :l foo_typeable.hs 
[1 of 1] Compiling Main             ( foo_typeable.hs, interpreted )
Ok, modules loaded: Main.
*Main> foo "123"
*** Exception: i dunno
*Main> foo 1
*** Exception: i dunno
*Main> foo (1 :: Int)
Int 1
*Main> foo (1 :: Integer)
*** Exception: i dunno
*Main> foo (1 :: Double)
Double 1.0
3 голосов
/ 04 мая 2011

Эта версия не ограничивается Bool, Int или Double, но String выглядит как [Char].

foo :: Typeable a => a -> String
foo = show . typeOf
...