轨道
/
Elm
Elm
/
练习
/
贝蒂的自行车店
贝蒂的自行车店

贝蒂的自行车店

学习练习

简介

基础 2

导出函数

导出函数在第一个概念中已经讲过,这里快速回顾一下。

Elm 中的每个文件都是一个模块,并且必须在所有其他代码之前包含一条 module 语句。

模块名必须与文件名一致,所以模块 Calculator 必须放在文件 Calculator.elm 中,模块 Parser.Utils 必须放在文件 Parser/Utils.elm 中。

模块中定义的所有内容都只属于该模块的私有作用域,除非在 exposing 中列出,否则无法从模块外部访问。

-- Calculator.elm
-- Define the Calculator module, and expose the `add` function
module Calculator exposing (add)

six = 3 + 3

add number1 number2 = number1 + number2
-- Calculator.elm
-- Define the Calculator module, and expose everything within: `six` and `add`
module Calculator exposing (..)

six = 3 + 3

add number1 number2 = number1 + number2

https://elm-lang.org/docs/syntax#modules

从其他模块导入函数

要访问其他模块中定义的函数,需要通过导入来实现。 导入某个模块时,该模块公开的所有函数都会变得可以访问。 但访问它们的方式取决于模块的导入方式。

默认是限定导入,访问这类模块中的函数(例如 List 模块中的 map 函数)时,需要在前面加上模块名(List.map)。

开放导入可以直接访问该模块中公开的函数,无需加前缀。使用 exposing 关键字即可,它与导出时用的那个关键字正好相对。你可以公开所有可用的函数(用 ..),也可以只公开特定的函数(例如 map)。

你还可以从其他模块导入类型及其构造函数,这会在后面的概念中讲到。

推荐使用限定导入,这样更清晰,也能避免命名冲突。

-- qualified imports
import List                            -- List.map, List.foldl
import List as L                       -- L.map, L.foldl

-- open imports
import List exposing (..)              -- map, foldl, concat, ...
import List exposing ( map, foldl )    -- map, foldl, List.concat

https://elm-lang.org/docs/syntax#modules

类型注解

类型注解的写法是 name : parameter types -> return type,多个形参类型之间也用 -> 分隔。

add : Int -> Int -> Int
add number1 number2 = number1 + number2

可以用括号来定义函数的形参(形参本身也用同样的语法定义,所以才需要括号)。

-- Transform every character in a string
map : (Char -> Char) -> String -> String
map charMapperFunction string =
    -- ...

https://elm-lang.org/docs/syntax#type-annotations

数字

Elm 中有两种数字类型,分别由 Int 和 Float 类型定义。 Int 对应正整数和负整数组成的集合。 Float 对应实数集合,受计算机精度的限制。 为数字定义的运算通常只适用于其中一种类型,不能把两者混用。 也有一些函数可以在两者之间转换:toFloat 把 Int 转换为 Float,而 round、floor、ceiling 或 truncate 则以各自的语义把 Float 转换为 Int。

https://package.elm-lang.org/packages/elm/core/latest/Basics#Int

字符串操作

为了在代码中表示单词和句子,Elm 有一个原生的 String 类型。 字符串字面量写在双引号之间,例如 "Hello World!"。 默认可以使用字符串拼接运算符 ++ 和相等运算符 ==。

hello : String -> String
hello subject = "Hello " ++ subject

hello "World!" --> "Hello World!"

其他大多数字符串函数都在 String 模块中,需要先导入才能使用。

https://package.elm-lang.org/packages/elm/core/latest/String

说明

在这个练习中,你将编写一些代码来帮助 Betty's Bike Shop,这是一家在线销售自行车和配件的商店。 你有三个任务,目标是在网站上正确地显示自行车和配件的价格。

1. 导出penceToPounds函数

你的同事已经写好了这个模块的骨架,即两个尚未定义的函数penceToPounds和poundsToString。 但是,他们忘了导出penceToPounds函数,所以它目前对其他模块和测试套件都不可见。

把penceToPounds加入导出函数的列表。

2. 把便士换算成英镑

目前,价格以整数形式的便士存储(这家自行车店位于英国)。 在网站上,我们希望以英镑显示价格,其中 1.00 英镑等于 100 便士。 你的第二个任务是实现penceToPounds函数,它接收以Int表示的便士数量,并将其换算成等值的英镑,以Float返回。 你还应该为这个函数定义类型标注。

penceToPounds 106
    --> 1.06

3. 格式化价格,以便在网站上显示

由于 Betty's Bike Shop 的自行车以英镑出售,价格显示时应带上符号“£”。 因此,你的第三个任务是实现poundsToString函数,它接收以Float表示的英镑数量,并返回一个String,即前面加上英镑符号的价格。 String模块里有String.fromFloat函数,会对你有帮助。 使用String模块之前,你应该先导入它。 你还应该为poundsToString定义类型标注。

poundsToString 1.06
    --> "£1.06"
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Elm Exercism

准备好开始 贝蒂的自行车店 了吗?

注册 Exercism,借助 28 个概念110 个练习 和真人导师指导,学习并掌握 Elm,全部免费。