`Reader a (b -> c)` 和 `b -> Reader a c` 之间有什么区别吗?

问题描述 投票:0回答:1

(其他一些 mtl monad 也会带来同样的问题,但我们只用

Reader
来举例说明)

假设我需要以人类可读的方式显示某些内容,其中实现和行为细节取决于用户偏好,从配置中读取:

showIt :: Config -> Object -> String

如果用户配置只是读取而不是修改,那么不妨使用

Reader
来反映这一点:

showIt :: Reader Config (Object -> String)

但是等等,这和这个有什么不同:

showIt :: Object -> Reader Config String

虽然我几乎不知道

Reader
,但我确实尝试过这两种设计,而且它们看起来功能相同。我仍然想知道两者之间是否存在语义差异,也就是说,当其他一些 Haskellers 查看我的代码时,如果我使用其他设计,他们会解释不同的目的或含义吗? 如果是这样,那么在这种情况下应该首选哪种用法?

haskell monad-transformers reader-monad
1个回答
1
投票

Reader Config (Object -> String)
Object -> Reader Config String
有什么不同?

前者将

showIt
实现限制为
read
一次配置,然后生成一个必须适用于所有对象的字符串转换函数。后者允许实现根据输入对象决定读取什么配置(或者更确切地说,是否读取1)。

他们的使用模式有很大不同:

do
  showAny <- showIt
  let str1 = showAny object1
  let str2 = showAny object2
  return (str1 ++ " " ++ str2)

do
  let show1 = showIt object1
  let show2 = showIt object2
  str1 <- show1
  str2 <- show2
  return (str1 ++ " " ++ str2)

1:使用

Reader
monad,没有太多选择 - 你只能决定是否读取配置(或者:多久读取一次 - 但每次都是一样的)。对于其他 monad,读取配置的不同位可能涉及不同的文件系统或数据库访问等,差异会变得更大。

© www.soinside.com 2019 - 2024. All rights reserved.