本文介绍了为什么无法解决此HasField实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 GHC 8.2.1 .我有以下模块:

I'm using GHC 8.2.1. I have the following module:

{-# 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] }

我的问题是,当我同时导入了两个模块并且尝试执行以下操作时:

My problem is that when I have both modules imported and I try to do something like:

{-# 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 实例?

推荐答案

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

The problem is solved by enabling {-# LANGUAGE PolyKinds #-} in the Moat module which defines the HasField instance.

我想这与 HasField 类型类具有多种类型有关:

I suppose it has to do with HasField typeclass being poly-kinded:

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

这使我们可以定义这样的 HasField 实例,其中字段选择器是非 Symbol 类型的

This allows us to define HasField instances like this one, where the field selector is a non-Symbol type:

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

这篇关于为什么无法解决此HasField实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-18 16:27