在榆树理解型解构

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

我想了解所有这些类型都可以定义和模式在榆树匹配的不同方式。

当搜索代码来学习,我发现了一个JSON解码器的纯榆木的实现。该代码可以发现here和系列文章here

我不明白在场上的功能使用的样式:

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)

我不明白割舍的身体。为什么会出现这样的任务以及如何代码得到评估?怎么

Dict.get重点对象

处理和“绑定”到?

decodeKey对象= ...

试图解码值= ...

从根本上说,我想了解在让这样,它返回解码器attemptToDecode一些“有用”发生了什么。此外,有没有表达何意的更好的办法?

先感谢您!

elm
2个回答
2
投票

我觉得@ zh5使得在这个意义上,一个正确的观点:

  1. 这可能是要么不供你学习在这一点(不管是什么你试图完成)正确的榜样
  2. 或者,如果是这样,你应该能够理解它不问这个问题。

在另一方面,试图了解事情只是出于好奇是一件好事,即使它并不总是特别有用,所以我会尝试帮助。


这是field(我认为)的意图:

给我的“逻辑”的Decoder,我可以用它来解码领域,给我一个字段名。我将采取“逻辑”出你的Decoder的,把一些“额外的逻辑”在它上面找到一个JSON对象领域,我会给你一个新的Decoder回该组合逻辑。

所以,这“额外逻辑”被分成两个部分在上面的代码:

  1. attemptToDecode捕获用于确保任何正在被解码是JSON对象的逻辑。此JSON对象的值被表示为被萃取并上到第二部分通过一个字典。 (如果任何被解码不是对象的结果应该是一个错误,很明显。)
  2. decodeKey捕获逻辑的另一半。具有JSON对象在字典的形式的内容,现在我们应该发现场,并尝试使用是在Decoder提供的“逻辑”进行解码。这个逻辑被从解码器解构和在代码称为parameterAttempt。 (显然,如果该字段不能在JSON对象中发现的结果应该是一个错误。)

现在,attemptToDecodedecodeKey此时其是指parameterAttempt(通过该字段进行解码的原始逻辑),所以我们可以说,attemptToDecode捕获所需要的场从JSON对象解码整个逻辑。所以在这一点上,所有需要做的是包装这个逻辑回一个Decoder,这是代码说什么:

Decoder attemptToDecode

而且,你一定是对你自己的答案,在解码器捕获的逻辑函数的形式被捕获,而当这些功能相互引用他们的类型签名必须在最后热身赛。


0
投票

解码器的类型定义如下:

type Decoder a
    = Decoder (Value -> Result String a)

有一个数据构造带一个参数。这意味着,为了建立一个解码器,我们需要一个函数,它接受一个值,并返回一个结果字符串中:

f: Value -> Result String a -> Decoder a

在让内部的分配是建立功能,并作为构建块。与他们的类型定义阅读他们使事情变得更清晰。

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

attemptToDecode使用decodeKey,可以这样做,因为这两个回报

结果字符串中

任何对此的反馈是非常赞赏。

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