Task.perform AdjustTimeZone Time.here
我发现了以下类型签名:
-- ∵
AdjustTimeZone : Zone -> Msg
here : Task x Zone
perform : (a -> msg) -> Task Never a -> Cmd msg
-- ∴
perform AdjustTimeZone here : Cmd Msg
如何将Task x Zone
统一为Task Never a
?特别是,x
至Never
值得怀疑,而Zone
至a
则合理。
答案 0 :(得分:3)
我不是类型推断专家,但我认为说“ {x
统一为Never
”并不正确,并怀疑这是您困惑的根源。 x
和a
都是类型变量,除非有其他约束发生冲突,否则它们将统一使用这两种方式。因此,就像a
变成Zone
一样,x
变成Never
,而不是相反。
您可能还想知道为什么Time.here
的类型为Task x Zone
而不是Task Never Zone
,因为毕竟here
应该知道它是否会出错。我认为这是因为1)无关紧要(对于类型系统,尽管它当然对用户来说可能),2)它使其更易于组合。
因此,假设您想将Time.here
与其他可能发生错误的其他Task
进行排序。 Task.andThen
具有类型(a -> Task x b) -> Task x a -> Task x b
,其中x
(错误)类型变量在所有Task
中都相同。因此,如果Time.here
的类型为Task Never Zone
,则我们必须为andThen
提供函数Zone -> Task Never b
。那显然是行不通的。
我非常确定您可以执行TasK.here |> Task.mapError never |> Task.andThen (\zone -> ...)
,但是如果错误类型留为类型变量而不是被约束为Never
,则这并不是必须的。这不是问题,因为Task.here
不会产生任何x
,因此它统一为什么都没有关系。