我在擴大對Haskell setting record field based on field name string?的答案以添加通用getField
。我正在使用gmapQi
,如果遇到的子元素的類型與預期類型不匹配,我想要生成一個錯誤。我希望錯誤消息包含遇到的類型的名稱以及預期類型的名稱。功能如下:typeOf返回類型
{-# 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
)。
輝煌!謝謝 – pat 2011-12-30 22:59:25