首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Haskell记录编写可读的代码时遇到困难

使用Haskell记录编写可读的代码时遇到困难
EN

Stack Overflow用户
提问于 2018-11-15 21:55:58
回答 1查看 182关注 0票数 4

我对Haskell相当陌生,我一直在努力用记录来编写可读的代码。

我的具体问题是:

  1. 我还没有找到一种有效的策略来处理不同记录类型的字段之间的名称冲突。我发现我希望在多个不同的记录类型中使用相同的字段,而且名称冲突问题真的很烦人。最后,我选择了一些前缀来添加到我的所有字段中,这增加了详细的内容,阻碍了可读性。
  2. 使用嵌套记录会产生非常详细的代码。我发现 someFunction(foo.bar, 2 * foo.bar.baz) 在像Java或C++这样的语言中很容易读懂。在Haskell,我发现自己写这个是为了完成同样的事情。 someFunction (fooBar foo) (2 * barBaz (fooBar foo)) 这很难直观地解析,调用多个参数的函数很快就变得不可读了。为了使它更具可读性,我发现自己定义了中间值,它将从记录中提取字段,这更具有可读性,但增加了更多的代码行,因此以另一种方式损害了可读性。

是否有更好的方法来使用更具可读性的记录,或者我应该做些什么呢?只是用元组?用大量的参数写入函数,而不是将相关的值分组到记录中?还有别的吗?

EN

回答 1

Stack Overflow用户

发布于 2018-11-16 20:09:23

解决这个问题的一个办法(如注释中所建议的)是使用镜片。使用microlensmicrolens-th包(开始时这些包可能更简单):

代码语言:javascript
运行
复制
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}

import Data.List (nub)
import Lens.Micro ((^.), (^..))
import Lens.Micro.TH (makeFields)

newtype Name = Name String
  deriving Eq

data Person = Person { _personName :: Name }
makeFields ''Person

data Species = Dog | Cat
  deriving Eq

data Pet = Pet { _petName :: Name, _petSpecies :: Species }
makeFields ''Pet

-- ^. is an infix operator for view
uniquePersonNames :: [Person] -> [Name]
uniquePersonNames ps = nub (map (\p -> p ^. name) ps)

dogs :: [Pet] -> [Pet]
dogs ps = filter (\p -> p ^. species == Dog) ps

data Concert = Concert
  { _concertPerformers :: [Person]
  , _concertAttendees :: [Person]
  }
makeFields ''Concert

-- ^.. is an infix operator for toListOf
performerNames :: Concert -> [Name]
performerNames c = c ^.. performers . traverse . name

data House = House { _housePeople :: [Person], _housePet :: Pet}
makeFields ''House

houseSound :: House -> String
houseSound h = case h ^. pet . species of
    Dog -> "Woof!"
    Cat -> "Meow!"

有几个资源,以了解更多的镜头和其他种类的光学。一个特别初学者友好的资源Control.Lens.Tutorial

请注意,这种方法可能导致难以理解的错误(我相信generic-lens库有更好的错误消息,但我没有使用它),特别是当您开始盲目地使用事物时。我建议坚持基本原则(如链接教程中所示) --这将涵盖大部分用例。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53328448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档