开发者

'pattern matching' on Typeable types

开发者 https://www.devze.com 2023-03-02 15:57 出处:网络
Suppose, for example, we have the following data structure: data Foo = Bool Bool | Int Int | Double Double

Suppose, for example, we have the following data structure:

data Foo = Bool Bool | Int Int | Double Double

Now, is there an easier way to do this:

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

Has someone thought of making a syntax for pattern matching on Typeable types?


Use typeOf and guards:

foo x
    | tx == typeOf "str" = "string"
    | tx == typeOf True  = "bool"
    | otherwise          = "i dunno"
  where tx = typeOf x


You can use view patterns here, they are quite handy extension.

{-# 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"

Results:

*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


This version doesn't limit itself to Bool, Int, or Double, but a String comes out as [Char].

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

精彩评论

暂无评论...
验证码 换一张
取 消