Alg*_*mis 3 elm elm-architecture
我正在尝试使用端口将URL传递给Javascript,以便将用户重定向到另一个页面.我写了一个port module包含我的项目所需的所有端口:
port module Utils exposing (..)
port changePage : String -> Cmd Event
Run Code Online (Sandbox Code Playgroud)
然后,我在我的Elm文件中导入它:
type Event = PageChange String
import Utils exposing (changePage)
Run Code Online (Sandbox Code Playgroud)
但是编译器不喜欢它:
It looks like the keyword `import` is being used as a variable.
8| import Utils exposing (changePage)
^
Rename it to something else.
Run Code Online (Sandbox Code Playgroud)
所以我将端口定义移动到主文件:
type Event = PageChange String
port changePage : String -> Cmd Event
Run Code Online (Sandbox Code Playgroud)
但是编译器仍然不同意:
Port `changePage` has an invalid type.
28| port changePage : String -> Cmd Event
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You are saying it should be:
String -> Platform.Cmd.Cmd BmC.Index.Event
But you need to use the particular format described here:
<http://guide.elm-lang.org/interop/javascript.html#ports>
Run Code Online (Sandbox Code Playgroud)
所以我去看了那种特殊的格式port check : String -> Cmd msg.我不明白它msg来自哪里,所以我去检查代码,我仍然不明白那条线是什么意思.
哪里msg来的?什么type Cmd msg = Cmd意思?提前致谢.
import语句必须在任何函数或类型定义之前.这就是你在这段代码上遇到编译错误的原因:
type Event = PageChange String
import Utils exposing (changePage)
Run Code Online (Sandbox Code Playgroud)
关于端口的问题:Elm的端口是一个位于架构边缘的功能.它们允许使用不同的语言进行互操作,因此,无论出于何种目的,在幕后都会有一点魔力.
其他语言具有与其他语言互操作的类似"神奇"结构.Haskell有外部函数接口(FFI),C#有extern关键字来调用外部库.
定义Cmd是通过查看代码实际上没有意义的那些部分之一.
type Cmd msg = Cmd
Run Code Online (Sandbox Code Playgroud)
这并没有真正告诉我们多少,但那没关系.它更像是编译器在编译时填写的占位符.其他语言也这样做.Haskell经常使用底部调用let x = x in x来表示编译器实际实现的函数.
所以,除非你真的对Elm和Javascript之间的交叉实现感兴趣,否则它可以让它想象并接受魔法.
至于能够在端口中指定具体类型,这只是编译器团队的另一种选择.尽管a Cmd Event是唯一可以通过端口的东西,但他们选择强制使用泛型类型作为Cmd的类型参数.确切的拼写Cmd msg不是必需的.msg可能是小写的:
port check : String -> Cmd a
Run Code Online (Sandbox Code Playgroud)
Elm 中的端口声明按设计需要非常具体的类型定义注释。
首先,我建议查看阅读类型,尤其是在提到类型变量的段落中
之后,确保您熟悉通用数据结构,如果官方指南没有帮助,您可以查看我对类似问题的回答Understanding generic union types in Elm
端口有点混乱,所以我打开了一个问题JavaScript 互操作指南应该解释端口函数类型定义
port out : String -> Cmd msg
| |
| |
Concrete type Generic type
of outgoing with `msg` type variable
data
Outgoing port never sends messages,
but you need to specify the type so the
compiler can infer, that you can use
this command to send the outgoing values
in any module, that imports "out" function
Run Code Online (Sandbox Code Playgroud)
port in : (List String -> msg) -> Sub msg
| |
| |
A function, that accepts Has to be generic,
outgoing data and returns because it is going to be
a message. This function a subscription with the
is called "tagger" same type as "tagger" returns
Has to be generic, i.e. use
`msg` type variable
Run Code Online (Sandbox Code Playgroud)