Tôi đang mở rộng câu trả lời cho Haskell setting record field based on field name string? để thêm một số chung là getField
. Tôi đang sử dụng gmapQi
và tôi muốn tạo lỗi nếu loại phần tử phụ gặp phải không khớp với loại mong muốn. Tôi muốn thông báo lỗi bao gồm tên của loại đã gặp phải, cũng như tên của loại được mong đợi. Chức năng trông như thế này:typeOf trên loại trả lại
{-# 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
Vấn đề là, tôi không biết phải đặt ở vị trí của "???"
để có được những kiểu trả về của getField
chức năng (ví dụ: làm thế nào để cụ thể hóa v
từ chữ ký loại).
rực rỡ! Cảm ơn – pat