Это минимальный пример, взятый из Reflection-0.5.
{-# LANGUAGE Rank2Types, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
{-# OPTIONS_GHC -fno-cse -fno-full-laziness -fno-float-in #-}
import Control.Applicative
import Data.Proxy
newtype Zero = Zero Zero deriving (Show)
class ReifiesNum s where
reflectNum :: Num a => proxy s -> a
instance ReifiesNum Zero where
reflectNum = pure 0
В GHCi я получаю следующее:
>:t Zero
Zero :: Zero -> Zero
Это имеет смысл: я спрашиваю тип конструктора, который принимает ноль и возвращает ноль.
>:t reflectNum
reflectNum :: (ReifiesNum s, Num a) => proxy s -> a
Имеет смысл написать что-то вроде
>let x = Just (undefined::Zero)
>reflectNum x
потому что тип Just Zero соответствует переменным типа 'proxy s'.
Наконец, запутанная часть:
>:t (reflectNum Zero)
(reflectNum Zero) :: Num a => a
Я не понимаю, как тип конструктора Zero :: Zero -> Zero, по-видимому, соответствует переменным типа 'proxy s', но, очевидно, это так, потому что тип (refleNum Zero) просто 'a'.
Буду признателен за помощь в понимании этого примера, и ссылки на соответствующие концепции будут высоко оценены.
Спасибо