理解Elm中的类型分解
我试图理解在Elm中定义类型和模式匹配的所有不同方式 在搜索可供学习的代码时,我在纯Elm中找到了一个JSON解码器的实现。代码可以在文章系列中找到 我无法理解字段函数中使用的样式:理解Elm中的类型分解,elm,Elm,我试图理解在Elm中定义类型和模式匹配的所有不同方式 在搜索可供学习的代码时,我在纯Elm中找到了一个JSON解码器的实现。代码可以在文章系列中找到 我无法理解字段函数中使用的样式: type Value = Jnull | Jobject (Dict String Value) type Decoder a = Decoder (Value -> Result String a) decodeValue : Decoder a -> Value ->
type Value
= Jnull
| Jobject (Dict String Value)
type Decoder a
= Decoder (Value -> Result String a)
decodeValue : Decoder a -> Value -> Result String a
decodeValue (Decoder attemptToDecode) value =
attemptToDecode value
field : String -> Decoder a -> Decoder a
field key (Decoder parameterAttempt) =
let
decodeKey object =
Dict.get key object
|> Result.fromMaybe "couldn't find key"
|> Result.andThen parameterAttempt
attemptToDecode value =
case value of
Jobject foundIt ->
decodeKey foundIt
_ ->
Err "not an object"
in
Decoder attemptToDecode
为函数编写的测试如下所示:
test "decodes a field" <|
\_ ->
Jobject (Dict.singleton "nested" (Jnumber 5.0))
|> decodeValue (field "nested" int)
|> Expect.equal (Ok 5)
测试“解码字段”
Jobject(Dict.singleton“嵌套”(Jnumber 5.0))
|>解码值(字段“嵌套”int)
|>Expect.equal(Ok 5)
我不明白出租汽车的车身。为什么会有这样的赋值?代码是如何计算的?怎么样
Dict.get键对象
处理并“绑定”到
decodeKey对象=
attemptToDecode值=
从根本上说,我试图理解let中发生了什么,以便它返回一些对解码器尝试进行解码的“有用”信息。还有,是否有更好的方式表达意图
提前谢谢你 解码器类型定义为:
type Decoder a
= Decoder (Value -> Result String a)
有一个数据构造函数接受一个参数。这意味着为了构建解码器,我们需要一个函数,该函数接受一个值并返回一个结果字符串a:
f: Value -> Result String a -> Decoder a
let中的赋值是构建函数,用作构建块。阅读它们的类型定义可以让事情更清楚
let
decodeKey: Dict String Value -> Result String a
decodeKey object =
case Dict.get key object of
Just value ->
parameterAttempt value
Nothing ->
Err "couldn't find key"
attemptToDecode: Value -> Result String a
attemptToDecode value =
case value of
Jobject foundIt ->
decodeKey foundIt
_ ->
Err "not an object"
in
Decoder attemptToDecode
尝试进行解码使用解码键并且可以这样做,因为两者都返回
结果字符串a
非常感谢您对此的任何反馈。我认为@zh5的观点是正确的,即:
这是
字段
的意图(我假设):
给我一个解码器中的“逻辑”,我可以用它来解码一个字段
给我一个字段名。我将从您的解码器
中取出“逻辑”,
在上面添加一些“额外的逻辑”来查找
JSON对象中的字段,我将返回此字段
新的解码器中的逻辑
因此,“额外逻辑”在上述代码中分为两部分:
attemptodecode
捕获用于确保被解码的对象是JSON对象的逻辑。这个JSON对象的值表示为一个字典,该字典被提取并传递给第二部分
(如果被解码的东西不是对象,那么结果显然应该是错误的。)
decodeKey
捕获逻辑的另一半。将JSON对象的内容设置为字典的形式,现在我们应该找到字段并尝试使用解码器中提供的“逻辑”对其进行解码。此逻辑从解码器中解构,并在代码中称为parametertest
(显然,如果在JSON对象中找不到该字段,则结果应该是错误的。)
现在,attemptodecode
指的是decodeKey
,然后它指的是ParameterTest
(用于解码字段的原始逻辑),因此我们可以说attemptodecode
捕获了从JSON对象解码字段所需的全部逻辑。因此,在这一点上,需要做的就是将此逻辑包装回解码器中,这正是代码所说的:
解码器试图解码
当然,你自己的回答是正确的,解码器中捕获的逻辑是以函数的形式捕获的,当这些函数相互引用时,它们的类型签名必须在最后匹配。在我看来,你看到的示例比你的理解允许的更复杂,然后问一个在这里没有意义的问题,可能对其他人没有帮助。因为这个原因,我将不得不投票结束decodeKey对象
定义了一个名为decodeKey
的函数,其参数object
由下面的代码实现|>
是介绍文档中介绍的管道操作符。Dict.get key object
的结果通过管道传输到下面的代码。所有这些都是decodeKey
的实现。