"pattern matching" by type types

Suppose, for example, that 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`
  liftM Int    (cast x) `mplus`
  liftM Double (cast x)

Has anyone thought of creating syntax for pattern matching in Typeable types?

+3
source share
3 answers

Use typeOfand protective devices:

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

Here you can use viewing templates, this is a pretty convenient 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
+4

Bool, Int Double, String [Char].

foo :: Typeable a => a -> String
foo = show . typeOf
+3
source

All Articles