【发布时间】:2011-12-30 20:36:45
【问题描述】:
我将答案扩展到Haskell setting record field based on field name string? 以添加通用getField。我正在使用gmapQi,如果遇到的子元素的类型与预期的类型不匹配,我想生成一个错误。我希望错误消息包含遇到的类型的名称以及预期类型的名称。函数如下所示:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Generics
import Prelude hiding (catch)
import Control.Exception
getField :: (Data r, Typeable v) => Int -> r -> v
getField i r = gmapQi i (e `extQ` id) r
where
e x = error $ "Type mismatch: field " ++ (show i) ++
" :: " ++ (show . typeOf $ x) ++
", not " ++ (show . typeOf $ "???")
---------------------------------------------------------------------------------
data Foo = Foo Int String
deriving(Data, Typeable)
handleErr (ErrorCall msg) = putStrLn $ "Error -- " ++ msg
main = do
let r = Foo 10 "Hello"
catch (print (getField 0 r :: Int)) handleErr
catch (print (getField 0 r :: String)) handleErr
catch (print (getField 1 r :: Int)) handleErr
catch (print (getField 1 r :: String)) handleErr
问题是,我不知道用什么代替 "???" 来获取 getField 函数的返回类型(即如何从类型签名中具体化 v)。
【问题讨论】:
标签: haskell