简体   繁体   English

可键入类型的“模式匹配”

[英]'pattern matching' on Typeable types

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`
  liftM Int    (cast x) `mplus`
  liftM Double (cast x)

Has someone thought of making a syntax for pattern matching on Typeable types?有人想过为Typeable类型的模式匹配制定语法吗?

Use typeOf and guards:使用typeOf和守卫:

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] .此版本不限于BoolIntDouble ,但String[Char]的形式出现。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM