【问题标题】:Why is this HasField instance not being resolved?为什么这个 HasField 实例没有被解析?
【发布时间】:2017-08-13 10:04:13
【问题描述】:

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

{-# 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 实例没有被解析?

【问题讨论】:

    标签: haskell records


    【解决方案1】:

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

    我想这与 HasField 类型类被多类化有关:

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

    这允许我们定义像这样的HasField 实例,其中字段选择器是非Symbol 类型:

    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
    

    【讨论】:

      猜你喜欢
      • 2010-11-14
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 2016-07-12
      • 2012-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      相关资源
      最近更新 更多