Я расширяю ответ на Поле записи настройки Haskell на основе строки имени поля? чтобы добавить общий 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
из сигнатуры типа).