我想在 haskell 中比较两条记录,而不用一遍又一遍地定义记录数据类型的每个更改以及记录的所有元素的 2 个数据的每个函数。
我读过有关镜头的内容,但找不到相关示例, 并且不知道从哪里开始阅读文档。
示例,不起作用:
data TheState = TheState { number :: Int,
truth :: Bool
}
initState = TheState 77 True
-- not working, example:
stateMaybe = fmap Just initState
-- result should be:
-- ANewStateType{ number = Just 77, truth = Just True}
同样,我想比较这两种状态:
state2 = TheState 78 True
-- not working, example
stateMaybe2 = someNewCompare initState state2
-- result should be:
-- ANewStateType{ number = Just 78, truth = Nothing}
最佳答案
正如其他人在评论中提到的,创建不同的记录来保存字段的 Maybe
版本并进行手动转换很可能更容易。然而,有一种方法可以以更自动化的方式获取仿函数,例如映射字段。
它可能比您想要的更复杂,但可以使用名为更高种类数据(HKD)的模式和名为 barbies
的库来实现。 .
这是一篇关于该主题的精彩博客文章:https://chrispenner.ca/posts/hkd-options
这是我在您的具体示例中尝试使用港元的尝试:
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
-- base
import Data.Functor.Identity
import GHC.Generics (Generic)
-- barbie
import Data.Barbie
type TheState = TheState_ Identity
data TheState_ f = TheState
{ number :: f Int
, truth :: f Bool
} deriving (Generic, FunctorB)
initState :: TheState
initState = TheState (pure 77) (pure True)
stateMaybe :: TheState_ Maybe
stateMaybe = bmap (Just . runIdentity) initState
这里发生的是,我们将记录的每个字段包装在自定义 f
中。我们现在可以选择参数化 TheState
的内容,以便包装每个字段。现在,普通记录的所有字段都包含在Identity
中。但您也可以轻松获得该记录的其他版本。 bmap
函数可让您将转换从一种 TheState_
类型映射到另一种类型。
老实说,这篇博文在解释这一点上比我做得更好。我觉得这个主题很有趣,但我自己对它还很陌生。
希望这有帮助! :-)
关于haskell - 在haskell中是否有比较/更改一条/两条记录的规范方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57517301/