صادر کردن توابع در مفهوم اول بررسی شد؛ اینجا یک مرور سریع داریم.
هر فایل در 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
دسترسی به توابعی که در ماژولهای دیگر تعریف شدهاند، از طریق وارد کردن آن ماژولها انجام میشود. هنگام وارد کردن یک ماژول، همهی توابعی که آن ماژول آشکار کرده است در دسترس قرار میگیرند. اما شیوهی دسترسی به آنها بسته به نحوهی وارد کردن ماژول متفاوت است.
وارد کردن مقید حالت پیشفرض است و دسترسی به یک تابع در چنین ماژولی (مثلاً تابع map در ماژول List) با آوردن نام ماژول بهعنوان پیشوند (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، فروشگاهی آنلاین برای دوچرخه و قطعات، کمک کند. سه وظیفه دارید که هدفشان نمایش درست قیمت دوچرخهها و قطعات در وبسایت است.
penceToPounds
همکارتان پیشتر اسکلت ماژول را نوشته است: توابع تعریفنشدهی penceToPounds و poundsToString. اما یادش رفته است تابع penceToPounds را صادر کند، بنابراین در حال حاضر برای سایر ماژولها یا مجموعهی تست قابل مشاهده نیست.
تابع penceToPounds را به فهرست توابع صادرشده اضافه کنید.
در حال حاضر، قیمت بهصورت یک عدد صحیح بر حسب پنی ذخیره میشود (فروشگاه در بریتانیا قرار دارد). در وبسایت میخواهیم قیمت را بر حسب پوند نشان دهیم، که ۱٫۰۰ پوند معادل ۱۰۰ پنی است. وظیفهی دوم شما پیادهسازی تابع penceToPounds است؛ این تابع مقداری پنی از نوع Int میگیرد و آن را به پوند معادلش بهصورت Float تبدیل میکند. همچنین باید نوع این تابع را مشخص کنید.
penceToPounds 106
--> 1.06
از آنجا که دوچرخههای این فروشگاه به پوند فروخته میشوند، قیمتها باید همراه با نماد «£» نمایش داده شوند. بنابراین وظیفهی سوم شما پیادهسازی تابع poundsToString است؛ این تابع مقداری پوند از نوع Float میگیرد و قیمت را بهصورت String برمیگرداند، در حالی که نماد پوند در ابتدای آن قرار گرفته است. ماژول String تابع String.fromFloat را دارد که در این کار به کارتان میآید. پیش از استفاده از ماژول String، باید آن را وارد کنید. همچنین باید نوع poundsToString را مشخص کنید.
poundsToString 1.06
--> "£1.06"