haskell - 从没有模式匹配的 JSON 值字符串文本中提取文本
问题描述
这是 Json Value 的定义:
-- | A JSON value represented as a Haskell value.
data Value = Object !Object
| Array !Array
| String !Text
| Number !Scientific
| Bool !Bool
| Null
deriving (Eq, Show)
let value = String "myValue"
looking for => fromString value == "myValue" ??
fromString :: Value -> Text
我正在寻找一个函数,比如我可以从字符串中获取文本而无需进行一些模式匹配,显然这个函数将是不安全的……一个 fromString 就像 Data.Maybe 中的 fromJust 一样……Data.Lens 中的一些东西。埃森?
解决方案
正如 Thomas M. DuBuisson 在上述评论中暗示的那样,这听起来像是一个XY Problem。尽管如此,我还是会尽力解决细节问题。
从技术上讲,您可以轻松地编写一个带有 type 的函数Value -> Text
,尽管它需要模式匹配。我意识到 OP 请求一个没有模式匹配的函数,但请继续阅读:
-- Warning: UNSAFE!
fromString :: Value -> Text
fromString (String s) = s
这样的函数可以编译,但不安全!
*Q53961314 Q53961314> fromString $ String "myValue"
"myValue"
*Q53961314 Q53961314> fromString $ Number 42
"*** Exception: Non-exhaustive patterns in function fromString
虽然它适用于String
值,但它对于任何其他类型的值都会崩溃。虽然在技术上可以编写和编译像上面这样的不安全函数,但 AFAICT 它不被认为是惯用的 Haskell。
一个更好的选择是返回Maybe Text
. 使用模式匹配仍然很容易编写:
fromStringSafe :: Value -> Maybe Text
fromStringSafe (String s) = Just s
fromStringSafe _ = Nothing
这个函数是总的:
*Q53961314 Q53961314> fromStringSafe $ String "myValue"
Just "myValue"
*Q53961314 Q53961314> fromStringSafe $ Number 42
Nothing
如果您不想自己编写这样的函数,但更喜欢使用lens-aeson,您可以使用_String
棱镜:
Prelude Data.Aeson Data.Aeson.Lens Control.Lens> String "myValue" ^? _String
Just "myValue"
如您所知,这也是安全的,因为^? _String
返回Maybe Text
:
Prelude Data.Aeson Data.Aeson.Lens Control.Lens> Bool True ^? _String
Nothing
Prelude Data.Aeson Data.Aeson.Lens Control.Lens> Number 42 ^? _String
Nothing
如果您真的非常想要一个不安全的功能,您可以使用^?! _String
:
Prelude Data.Aeson Data.Aeson.Lens Control.Lens> String "myValue" ^?! _String
"myValue"
毫不奇怪,它是不安全的:
Prelude Data.Aeson Data.Aeson.Lens Control.Lens> Number 42 ^?! _String
"*** Exception: (^?!): empty Fold
CallStack (from HasCallStack):
error, called at src\\Control\\Lens\\Fold.hs:1285:28 in lens-4.17-7m3etWEBj0P3172qv7LEG9:Control.Lens.Fold
^?!, called at <interactive>:9:1 in interactive:Ghci3
不过,我想知道您为什么要问这种功能。您是否想通过 Aeson 解决我们可以帮助解决的具体问题?
推荐阅读
- postgresql - 无法连接到端口 5432 上的服务器(PostgreSQL - CentOS 7.4)
- c# - 使用公钥的 JWT 令牌验证
- android - Firebase Android:卸载应用程序后,经过身份验证的用户会发生什么?
- javascript - 如何将对象的嵌套属性添加到 FormData 对象?
- c - 为什么 \b 在字符串中间使用时会删除写在 \b 之前的一个字符,但在末尾使用时却没有?
- mysql - mysql追加到第一行,移动其他行
- excel - Excel 中的研究数据分析:x 倍列值的中位数
- symfony - Symfony 4 不鼓励捆绑,这是为什么呢?是什么取代了它们?
- javascript - 从 VueJS 组件发出的重复事件
- javascript - 将音频从 Kotlin/Spring 后端流式传输到前端