我正在使用DuplicateRecordFields(+ OverloadedLabels)扩展,我遇到了一个无法弄清楚如何在记录更新中消除歧义的情况。
这是一个简化的例子:
data A = A { name :: String }
data B = B { name :: String }
combine :: A -> B -> A
combine a b = a { name = name b }
有没有办法让这项工作?
答案 0 :(得分:2)
我之前回答过一个关于-XDuplicateRecordFields
的问题,目前GHC没有从其论证中推断记录字段的类型:
您现在可以做的是明确指定name
提取器的类型,如下所示:
{-# LANGUAGE DuplicateRecordFields #-}
data A = A { name :: String }
data B = B { name :: String }
combine :: A -> B -> A
combine a b = a { name = (name :: B -> String) b }
答案 1 :(得分:1)
您可以匹配模式中的名称:
data A = A { name :: String }
data B = B { name :: String }
combine :: A -> B -> A
combine a B{name = nb} = a { name = nb }
我不是DuplicateRecordFields
的粉丝。为什么不去the lens route?
{-# LANGUAGE TemplateHaskell, FlexibleInstances, FunctionalDependencies #-}
import Control.Lens
import Control.Lens.TH
data A = A { _aName :: String }
makeFields ''A
data B = B { _bName :: String }
makeFields ''B
combine :: A -> B -> A
combine a b = a & name .~ b^.name
答案 2 :(得分:0)
或者,您可以机械地使用getField
中的GHC.Records
来消除歧义,如下所示:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE TypeApplications #-}
module DRF where
import GHC.Records (getField)
data A = A { name :: String } deriving Show
data B = B { name :: String }
combine :: A -> B -> A
combine a b = a { name = getField @"name" b }
{- in ghci
Prelude DRF> a = A "Alice"
Prelude DRF> b = B "Bob"
Prelude DRF> DRF.combine a b
A {name = "Bob"}
-}
参考文献: