├── .gitignore ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | cabal-dev 3 | *.o 4 | *.hi 5 | *.chi 6 | *.chs.h 7 | *.dyn_o 8 | *.dyn_hi 9 | .virtualenv 10 | .hpc 11 | .hsenv 12 | .cabal-sandbox/ 13 | cabal.sandbox.config 14 | *.prof 15 | *.aux 16 | *.hp 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of haskell-to-elm nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # haskell-to-elm 2 | 3 | Collection of examples on places where Elm is different to Haskell. 4 | 5 | Used for helping beginners moving from Haskell to Elm. Non-exhaustive list, only to be used alongside the documentation on the [Elm](http://elm-lang.org) site. 6 | 7 | * [Functional Programming](#functional-programming) 8 | * [Type signatures](#type-signatures) 9 | * [Function application](#function-application) 10 | * [Function composition](#function-composition) 11 | * [List comprehensions](#list-comprenhensions) 12 | * [Lenses](#lenses) 13 | * [Where](#where-vs-let) 14 | * [Purity](#purity) 15 | * [Prelude functions](#built-in-prelude-methods) 16 | * [id](#id) 17 | * [cons](#cons) 18 | * [head](#head) 19 | * [tail](#tail) 20 | * [zip](#zip) 21 | * [show](#show) 22 | * [mod](#mod) 23 | * [unwords](#unwords) 24 | * [cycle](#cycle) 25 | * [foldl](#foldl) 26 | * [Modules](#module-syntax) 27 | * [Importing](#importing-names) 28 | * [Exporting](#defining-exportable-names) 29 | 30 | # Functional programming 31 | 32 | ## Type signatures 33 | 34 | Elm uses a [single colon `(:)`](http://elm-lang.org/docs/syntax#type-annotations) for type signatures. Double colons `(::)` is used for [cons](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/List#::). 35 | 36 | Example 37 | 38 | ``` 39 | add :: Int -> Int 40 | ``` 41 | 42 | becomes 43 | ``` 44 | add : Int -> Int 45 | ``` 46 | 47 | ## Function application 48 | 49 | Instead of using the dollar symbol `$` elm uses `<|` and `|>` for [application in different directions](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Basics#|>). 50 | 51 | Example: 52 | 53 | ``` 54 | collage (round board.width) (round board.height) $ map (genRect board) board.pieces 55 | ``` 56 | becomes 57 | ``` 58 | collage (round board.width) (round board.height) <| List.map (genRect board) board.pieces 59 | -- 60 | List.map (genRect board) board.pieces |> collage (round board.width) (round board.height) 61 | ``` 62 | 63 | ## Function composition 64 | 65 | Instead of using the `(.)` symbol Elm uses `<<` and `>>` for [composition in different directions](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Basics#>>) 66 | 67 | Example: 68 | ``` 69 | isEvenSquareRoot = isEven . sqrt 70 | ``` 71 | becomes 72 | ``` 73 | isEvenSquareRoot = sqrt >> isEven 74 | -- or 75 | isEvenSquareRoot = isEven << sqrt 76 | ``` 77 | 78 | ## List comprenhensions 79 | 80 | There are [no list comprehensions](https://github.com/elm-lang/elm-compiler/issues/147#issuecomment-17439271) in Elm. 81 | 82 | ## Lenses 83 | 84 | Elm has the package [focus](http://package.elm-lang.org/packages/evancz/focus/1.0.1) for lense-like accessors. Due to a lack of template-haskell like functionality, you must always [manually create your own focus](http://package.elm-lang.org/packages/evancz/focus/1.0.1/Focus#create) 85 | 86 | 87 | 88 | Example: 89 | ``` 90 | data Patch = Patch { 91 | _colour :: Colour, 92 | _size :: Double, 93 | _coord :: Coordinate 94 | } deriving (Show, Eq, Ord) 95 | 96 | mkLabels[''Patch] 97 | ``` 98 | becomes 99 | ``` 100 | type alias Patch = { 101 | colour: Colour, 102 | size: Float, 103 | coord: Coordinate 104 | } 105 | 106 | colour = create .colour (\f r -> { r | colour = f r.colour }) 107 | coord = create .coord (\f r -> { r | coord = f r.coord }) 108 | size = create .size (\f r -> { r | size = f r.size }) 109 | ``` 110 | 111 | ## where vs let 112 | 113 | Elm has no where binding - instead use [let](http://elm-lang.org/docs/syntax#let-expressions) 114 | 115 | ## Pattern matching 116 | 117 | Elm doesn't support multiple body declarations for functions, so instead you have to use [case..of](http://elm-lang.org/docs/syntax#conditionals) 118 | 119 | Example: 120 | ``` 121 | head [] = error 122 | head (X:xs) = x 123 | ``` 124 | becomes 125 | ``` 126 | head xs = case xs of 127 | x::xs -> Just x 128 | [] -> Nothing 129 | ``` 130 | 131 | ## Purity 132 | 133 | Functions in Elm as of 0.15.1 have pure type signatures. However, as they are actually implented in JS, it's possible that the underlying code you're calling isn't pure. This gives the effect of Elm the language being pure, but the things it can be used to do can be impure (eg, drawing to screen). Native functions can also produce runtime errors, though there is a drive to rid these from Elm entirely. 134 | 135 | # Built-in (Prelude) methods 136 | 137 | ## id 138 | 139 | Elm has renamed id to [identity](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Basics#identity) 140 | 141 | Example: 142 | ``` 143 | id xs 144 | ``` 145 | becomes 146 | ``` 147 | identity xs 148 | ``` 149 | 150 | ## cons 151 | 152 | Elm uses [double colons `(::)`](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/List#::) for cons. 153 | 154 | Example 155 | ``` 156 | 5 : 6 : [7, 8] 157 | ``` 158 | becomes 159 | ``` 160 | 5 :: 6 :: [7, 8] 161 | ``` 162 | 163 | ## head 164 | 165 | Instead of throwing errors for empty lists, Elm uses Maybe for [head](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/List#head) 166 | 167 | Example 168 | ``` 169 | head [4, 5] == 4 170 | ``` 171 | becomes 172 | ``` 173 | case head [4, 5] of 174 | Just x -> x == 4 175 | Nothing -> False 176 | ``` 177 | 178 | ## tail 179 | 180 | Instead of throwing errors for empty lists, Elm uses Maybe for [tail](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/List#tail) 181 | 182 | Example 183 | ``` 184 | tail [4, 5] == [5] 185 | ``` 186 | becomes 187 | ``` 188 | case tail [4, 5] of 189 | Just x -> x == [5] 190 | Nothing -> False 191 | ``` 192 | 193 | ## zip 194 | 195 | Elm has [no built-in zip](http://elm-lang.org/examples/zip) method - instead it provides a [map2](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/List#map2) function that can be used with the tuple creator `(,)` to make a list of size 2 tuples from two lists. 196 | 197 | Example: 198 | 199 | ``` 200 | zip xs ys 201 | ``` 202 | becomes 203 | ``` 204 | map2 (,) xs ys 205 | ``` 206 | 207 | 208 | ## show 209 | 210 | Elm renamed [show](http://zvon.org/other/haskell/Outputprelude/show_f.html) to [toString](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Basics#toString). Confusingly, there is also a [method called show](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Graphics-Element#show) in Elm - this generates a HTML element containing a textual representation of the data. 211 | 212 | Example: 213 | ``` 214 | show [1, 2, 3] 215 | ``` 216 | becomes 217 | ``` 218 | toString [1, 2, 3] 219 | ``` 220 | 221 | ## mod 222 | 223 | mod in Elm uses the [`(%)` symbol](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Basics#%). 224 | 225 | Example: 226 | ``` 227 | isEven x = x `mod` 2 == 0 228 | ``` 229 | becomes 230 | ``` 231 | isEven x = x % 2 == 0 232 | ``` 233 | 234 | ## unwords 235 | 236 | unwords is replaced by the [join function](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/String#join) 237 | 238 | Example: 239 | ``` 240 | unwords $ words "Hello Dave and Jeremy" 241 | ``` 242 | becomes 243 | ``` 244 | join " " <| words "Hello Dave and Jeremy" 245 | ``` 246 | 247 | ## cycle 248 | 249 | Elm has no cycle built in. 250 | 251 | 252 | TODO: find documentation for this 253 | 254 | ## foldl 255 | 256 | The order of the accumalator function arguments are [swapped in Elm](http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Set#foldl). 257 | 258 | Example: 259 | ``` 260 | idx xs = foldl (\x y -> y : x) [] xs 261 | ``` 262 | becomes 263 | ``` 264 | id xs = List.foldl (\x y -> x :: y) xs [] 265 | ``` 266 | 267 | # Module syntax 268 | 269 | ## Importing names 270 | 271 | Elm uses the [`exposing` keyword](http://elm-lang.org/docs/syntax#modules) to import names into the current namespace. 272 | 273 | Example: 274 | ``` 275 | import List (map, foldl) 276 | ``` 277 | becomes 278 | ``` 279 | import List exposing (map, foldl) 280 | ``` 281 | 282 | ## Defining exportable names 283 | 284 | TODO: find documentation on elm site for this 285 | 286 | Following the module declaration, you must have *no* identnation level. 287 | 288 | Example: 289 | ``` 290 | module Coords (pos) where 291 | pos x y = (x, y) 292 | ``` 293 | becomes 294 | ``` 295 | module Coords exposing (pos) 296 | pos x y = (x, y) 297 | ``` 298 | --------------------------------------------------------------------------------