在Elm中使用Maybe读取FileReader类型

 2020-10-19 

Reading a FileReader type with a Maybe in elm

(这与在Elm中初始化一个空文件值有关)

我正在使用Elm(0.18)和导入的simonh1000的FileReader库。 要存储文件值,我们使用以下json类型:

1
2
type alias FileContentArrayBuffer =
    Value

因此,我构建了模型:

1
2
3
4
5
6
7
8
9
10
11
12
type alias Model =
  {
     username : String
   , filecontent: Maybe FileContentArrayBuffer
  }

initialModel : Model
initialModel =
  {
     username ="mark"
   , filecontent = Nothing
  }

将文件放到适当位置后,将调用getFileContents。 相关功能和消息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
getFileContents : NativeFile -> Cmd Msg
getFileContents nf =
    FileReader.readAsArrayBuffer nf.blob
        |> Task.attempt OnFileContent



type Msg
...
    | OnFileContent (Result FileReader.Error (Maybe FileContentArrayBuffer))



update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
...
        OnFileContent res ->
            case res of
                Ok (Just filecontent) ->
                    ( { model | filecontent = filecontent }, Cmd.none )

                Ok Nothing ->
                    Debug.crash"No Content"

                Err err ->
                    Debug.crash (toString err)

编译时出现此错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
The right side of (|>) is causing a type mismatch.

56|     FileReader.readAsArrayBuffer nf.blob
57|>        |> Task.attempt OnFileContent

(|>) is expecting the right side to be a:

    Task.Task FileReader.Error FileReader.FileContentArrayBuffer -> a

But the right side is:

    Task.Task FileReader.Error (Maybe FileReader.FileContentArrayBuffer)
    -> Cmd Msg

考虑到我已经在类型中提供了Maybe并提供了大小写,所以不确定为什么。 有任何想法吗?


如果您这样定义Msg

1
2
3
type Msg
...
    | OnFileContent (Result FileReader.Error FileContentArrayBuffer)

然后,您的更新案例可以在成功时设置文件值,或设置为Nothing in failure:

1
2
3
4
5
6
7
    OnFileContent res ->
        case res of
            Ok filecontent ->
                ( { model | filecontent = Just filecontent }, Cmd.none )

            Err err ->
                ( { model | filecontent = Nothing }, Cmd.none )

请注意,应不惜一切代价避免Debug.crash。 它确实只是用于临时调试。 最好在模型上添加错误消息属性,以将问题通知用户。