3

例如,假设我们有以下数据结构:

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)

有人想过为Typeable类型的模式匹配制定语法吗?

4

3 回答 3

6

使用typeOf和防护:

foo x
    | tx == typeOf "str" = "string"
    | tx == typeOf True  = "bool"
    | otherwise          = "i dunno"
  where tx = typeOf x
于 2011-05-04T15:39:01.457 回答
4

您可以在此处使用视图模式,它们是非常方便的扩展。

{-# 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] 编译 Main(foo_typeable.hs,解释)
好的,已加载模块:主要。
*主> foo "123"
*** 例外:我不知道
*主> foo 1
*** 例外:我不知道
*Main> foo (1 :: Int)
诠释 1
*Main> foo (1 :: 整数)
*** 例外:我不知道
*Main> foo (1 :: Double)
双1.0
于 2011-05-04T21:57:05.307 回答
3

此版本不限于BoolIntDouble,而是String[Char].

foo :: Typeable a => a -> String
foo = show . typeOf
于 2011-05-04T15:43:41.987 回答