Advertisement
Guest User

gab

a guest
Feb 15th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.59 KB | None | 0 0
  1. ---------------------------------------------------------------------------------------
  2. -- Imports
  3.  
  4. use std::collections::HashMap -- Alias HashMap module, use it now as HashMap::new/1
  5. use std::collections::HashMap::* -- Import HashMap functions, use it now as: new/1
  6. use std::io::Error::Error -- Import Error variant and every variant name into namespace
  7. -- This means that now I can use:
  8. -- | Error::CannotOpenFile
  9. -- | CannotOpenFile
  10.  
  11. ---------------------------------------------------------------------------------------
  12. -- Record types.
  13. -- Used to give an alias to a record.
  14. -- This is totally equivalent to: { name : String, age : Int }
  15. type User =
  16. name : String
  17. age : Int
  18.  
  19. -- Type variants
  20. type UserStatus =
  21. | LoggedIn
  22. | LoggedOut(DateTime)
  23.  
  24. -- HKT
  25. type List =
  26. | Cons(a, List(a))
  27. | Nil
  28.  
  29. -- Updating type field
  30. update_name(user : User) -> User =
  31. { user | name = "Updated: ${user.name}" }
  32.  
  33. ---------------------------------------------------------------------------------------
  34. -- Protocols
  35. -- Inside the definition of a protocol, self is used
  36. -- to refere to the type implementing it
  37. protocol Debug =
  38. fmt(Self) -> String
  39.  
  40. -- 2 generic types here:
  41. -- self: probably List(a)
  42. -- a : type of a single element inside List
  43. protocol Iterator =
  44. next(Self) -> Result(a)
  45.  
  46. ---------------------------------------------------------------------------------------
  47. -- Implementation block
  48. impl Debug for User =
  49. fmt(self) -> String =
  50. "{ name = ${self.name}, age = ${self.age} }"
  51.  
  52. -- Extension functions
  53. -- Can be used in any module on any exported type
  54. -- In case of conflincting signatures, an error is thrown.
  55. -- Overloading is allowed.
  56. impl User =
  57. print_name(self) -> Unit =
  58. IO::println(self.name)
  59.  
  60. impl User =
  61. print_name(self, out : Writer) -> Unit =
  62. Writer::write(out, self.name)
  63.  
  64. impl User =
  65. print_name(self, console : Console) -> Unit =
  66. Console::println(console, self.name)
  67.  
  68. -- HKT applied to impl block
  69. impl Iterator(a) for List(a) =
  70. next(self) -> Result(a) =
  71. pass
  72.  
  73. ---------------------------------------------------------------------------------------
  74. -- Constants
  75.  
  76. const PI = "3.14"
  77. pub const SERVER_URL = "https://google.com"
  78.  
  79. ---------------------------------------------------------------------------------------
  80. -- Assignment
  81. -- Only possible inside let block.
  82. something() -> String =
  83. let
  84. result = "hello world"
  85. in
  86. result
  87.  
  88. -- Pattern matching in let returns the value
  89. -- if it doesn't match.
  90. something() -> String =
  91. let
  92. Ok(user) = get_user_from_cache() -- Could return Error(_)
  93. Ok(age) =
  94. case user.age of
  95. | it < 18 -> Error()
  96. | _ -> Ok(user.age)
  97. in
  98. pass
  99.  
  100. -- With destructuring
  101. something() -> String =
  102. let
  103. {name, age} = { name = "Gabriel", age = 23 }
  104. (first, second) = ("First", "Second")
  105. in
  106. pass
  107.  
  108. ---------------------------------------------------------------------------------------
  109. -- Conditionals
  110. log(val : Debug) -> Unit =
  111. case System::env() of
  112. | Prod -> ()
  113. | _ -> IO::println(val)
  114.  
  115. -- To simulate an if/else, use case of without arguments.
  116. -- It expects every left arm of a branch to evaluate to a boolean value.
  117. something(name : String) -> String =
  118. case of
  119. | isPeter(name) -> pass
  120. | isMario(name) -> pass
  121. | isAngelo(name) -> pass
  122.  
  123. ---------------------------------------------------------------------------------------
  124. -- Functions
  125.  
  126. -- The most basic function. Its always required to specify the return type,
  127. -- even if it's Unit.
  128. something() -> Unit =
  129. pass
  130.  
  131. -- With params and return value
  132. new_user(name : String, age : Int) -> User =
  133. pass
  134.  
  135. -- With default value
  136. new_user(name : String, age : Int = 18) -> User =
  137. pass
  138.  
  139. -- With generic type
  140. append_to_list(list : List(a), elem : a) -> List(a) =
  141. pass
  142.  
  143. ---------------------------------------------------------------------------------------
  144. -- Lambdas
  145.  
  146. double(coll : List(Int)) -> List(Int) =
  147. Enum::map(coll) { it * 2 }
  148.  
  149. ---------------------------------------------------------------------------------------
  150. -- Function call
  151.  
  152. -- From current scope
  153. something() -> Int =
  154. multiply(2, 3)
  155.  
  156. -- From an external module
  157. something() -> HashMap(String, Int) =
  158. HashMap::new()
  159.  
  160. -- With named arguments
  161. something() -> Int =
  162. multiply(first = 2, second = 3)
  163.  
  164. ---------------------------------------------------------------------------------------
  165. -- Pipe operator
  166. -- Pipes into the first argument of the function.
  167. -- Every function requires brackets.
  168. something() -> String =
  169. divide(30, 10)
  170. |> multiply(10)
  171. |> add(5)
  172. |> toString()
  173.  
  174. ---------------------------------------------------------------------------------------
  175. -- Visibility modifiers
  176.  
  177. -- Private, only visible inside module
  178. something() -> Unit =
  179. pass
  180.  
  181. -- Public, visible to other modules as well
  182. pub something() -> Unit =
  183. pass
  184.  
  185. ---------------------------------------------------------------------------------------
  186. -- Annotations
  187.  
  188. -- since("1.0.0")
  189. -- deprecated("Use String.join/3 instead", level = WARNING)
  190. join(s : List(String), sep : String) -> String =
  191. pass
  192.  
  193. ---------------------------------------------------------------------------------------
  194. -- Testing
  195. -- First class citizien, with custom constructs.
  196.  
  197. suite "User" =
  198. -- Run initially
  199. init =
  200. let
  201. user = User::new("Gabriel")
  202. in
  203. { user = user }
  204.  
  205. -- Run before each test
  206. before =
  207. pass
  208.  
  209. -- Run after each test
  210. after =
  211. pass
  212.  
  213. test "name should always be Gabriel" =
  214. assert(True) { self.user.name == "Gabriel" }
  215.  
  216. test "name should never be another thing than Gabriel" =
  217. assert(False) { self.user.name == "Luigi" }
  218.  
  219. test "should not be present in cache by default" =
  220. let
  221. Ok(cache) = get_global_cache()
  222. in
  223. assert(Error(Cache::Error::ValueNotPresent)) {
  224. Cache::get(cache, "user")
  225. }
  226.  
  227. ---------------------------------------------------------------------------------------
  228. -- Things in the standard library
  229.  
  230. -- Option and Result replaced by Result
  231. -- Two type exists: Result/1 and Result/2
  232. -- It allows always for exaustive pattern matching
  233.  
  234. type Result =
  235. | Ok(a)
  236. | Error(e = CommonError)
  237.  
  238. type CommonError =
  239. | NotFound
  240. | InvalidFormat
  241.  
  242. -- Usage
  243. something() -> Result(Int) =
  244. case of
  245. | False -> Ok()
  246. | False -> Error(Nothing)
  247. | True -> Error(InvalidFormat)
  248.  
  249. case something() of
  250. | Ok(val) -> IO::println(val)
  251. | Error(NotFound) -> IO::println("Not Found")
  252. | Error(_) -> pass
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement