Con*_*ean 6 functional-programming overloading pattern-matching elm
我正在尝试从JS移植一个库,我已经找到了一个可以接受字符串或字符串列表的函数.如果给定一个字符串,它会将其拆分为一个字符串列表,然后继续,就好像它首先被传递一样.
我可以通过定义自己的类型来做到这一点,但它会使API变得丑陋,并且需要为数据添加自定义类型前缀.
这是我得到的:
type DocumentBody = Raw String | Words List String
tokenize: DocumentBody -> List String
tokenize s =
case s of
Raw str_body -> String.split " " str_body |> (List.map String.toLower)
Words list_body -> List.map String.toLower list_body
-- Tests
tests =
suite "Tokenizer"
[ test "simple" <| assertEqual ["this", "is", "a", "simple", "string"]
<| tokenize (Raw "this is a simple string")
, test "downcasing tokens: string" <| assertEqual ["foo", "bar"]
<| tokenize (Raw "FOO BAR")
, test "downcasing tokens: list of str" <| assertEqual ["foo", "bar"]
<| tokenize (Words ["Foo", "BAR"])
]
Run Code Online (Sandbox Code Playgroud)
最终,我不认为端口应该支持这种行为,但是如何在类型的枚举上模式匹配而不是需要前缀Raw或Words在我的示例中?
不,您不能像使用其他语言一样以Elm重载函数。每个功能都有一个签名。如果您希望函数接受可以是多种类型的参数,则使用联合类型的解决方案就可以了。
您说它使API难看。我不会觉得丑陋。类型声明或case语句的语法可能并不吸引人,但我说,给它一点时间。它会在你身上成长。那里有很多电源和安全性。您不会让代码做任何假设,而是被迫处理每种情况,这是使用Elm之类的语言的优势之一。
您的模式匹配代码是合适的。您不能将其缩短到此以外。
同时,我可以理解重写JavaScript库并尝试通过原始JavaScript通过端口进行通信的痛苦。您正在用更严格的语言重写内容,并且您将无法复制使用javascript接受任何内容的函数签名。但这又是榆树的强项,而不是弱项。借此机会加强API并消除歧义。
对于您的特定示例,在我看来,您的解决方案之外还有其他可能的选择。我认为该tokenize功能从一开始就很有希望。这太含糊了。用功能语言编写代码时,我更喜欢使内容小巧且可组合。对我来说,它实际上应该是两个单独的功能,每个功能都有一个特定的目的。
| 归档时间: |
|
| 查看次数: |
811 次 |
| 最近记录: |