2017-08-13 84 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 
相關問題