2017-08-13 85 views
3

我正在使用GHC 8.2.1。我有以下模块:为什么这个HasField实例没有被解析?

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE UndecidableInstances #-} 
{-# LANGUAGE TypeApplications #-} 
{-# LANGUAGE ScopedTypeVariables #-} 
module Moat (Moat,moat) where 

import GHC.Records (HasField(..)) 

newtype Moat r = Moat r 

moat :: r -> Moat r 
moat = Moat 

instance HasField s r v => HasField s (Moat r) v where 
    getField (Moat r) = getField @s r 

这等一个:

module Foo (Foo(..)) where 

data Foo a = Foo { getDims :: (Int, Int), getData :: [a] } 

我的问题是,当我有两个模块进口,我尝试做这样的事情:

{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE TypeApplications #-} 
{-# LANGUAGE DataKinds #-} 
import Moat 
import Foo 
import GHC.Records 

oops :: (Int,Int) 
oops = getField @"getDims" (moat (Foo (5,5) ['c'])) 

我得到这个错误:

No instance for (HasField "getDims" (Moat (Foo Char)) (Int, Int)) 
     arising from a use of ‘getField’ 

为什么HasField实例无法解析?

回答

4

该问题通过在Moat模块中启用{-# LANGUAGE PolyKinds #-}来解决,该模块定义了实例。

我想这与HasField类型类是聚kinded做:

λ :info HasField 
class HasField k (x :: k) r a | x r -> a where 
    getField :: r -> a 

这允许我们定义这样一个,在字段选择是非SymbolHasField实例:

import GHC.Records 
data A = A B 
data B = B deriving Show 
instance HasField B A B where 
    getField (A b) = b 

在ghci的:

λ> getField @B (A B) 
B 
相关问题