typeOf on return type

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

7
задан Community 23 May 2017 в 12:27
поделиться