Basics
Comments
Line and block comments
Haskell
––Haskell line comment
{––
Haskell block comment
––}
F#
// F# line comment
(*
F# block comment
*)
Lists
List of integers
Tuples
Tuples in F# are the same as in Haskell
Boolean operations
Haskell
(5 > 3 && “abc” /= “def”) || (”abc” == “abc”)
F#
(5 > 3 && “abc” <> “def”) || (”abc” = “abc”)
Variables
Declaring variable str of infered type string
Note: Variables can contain more than just a simple value (e.g. expressions)
Function composition
Double filtered even numbers
Haskell
(map (\\x -> x * x) . filter (\\x -> x `rem` 2 == 0))
[1,2,3,4,5]
F#
((List.filter (fun x -> x % 2 = 0)) >>
(List.map (fun x -> x * x))) [1;2;3;4;5] –– [4,16]
Pipes
F#
((List.filter (fun x -> x % 2 = 0)) [1;2;3;4;5] |>
(List.map (fun x -> x * x))) // [4;16]
let .. in ..
Haskell
let x = 4; y = 2 in x + y
F#
let x = 4 and y = 2 in x + y
Functions
Simple function
Parameter type inference
Simple function
Parameter type explicitly defined
Haskell
square :: Int -> Int
square n = n * n
F#
let square (n:int) = n * n
Recursive function, if - else
Factorial function using ‘if - else’ statement. It is recursive function which must be explicitly marked with rec keyword in F#
Haskell
fac :: Int -> Int
fac n = if n > 1 then n * fac(n-1) else 1
F#
let rec fac n = if n > 1 then fac n * (n-1) else 1
Recursive function, pattern matching
Factorial function using pattern matching
Haskell
fac :: Int -> Int
fac 0 = 1
fac 1 = 1
fac n = n * fac (n-1)
In F#, keyword function enables using simplified way of pattern matching in functions. Parameters are infered from pattern, they can’t be explicitly defined here.
F#
let rec fac = function
| 0 | 1 -> 1
| n -> n * fac (n-1)
This is an alternative using match for pattern matching with explicitly defined parameter type
F#
let rec fac (n:int) = match n with
| 0 | 1 -> 1
| n -> n * fac (n-1);;
Function as a parameter
Function requiring a function (int -> int) as a parameter. Implementation of a map function for list of integers
Haskell
mapInt :: (Int -> Int) -> [Int] -> [Int]
mapInt _ [] = []
mapInt f (x:xs) = f x : mapInt f xs
F#
let mapInt (f:int -> bool) (xs:int list)
= match xs with
| [] -> []
| (n::ns) -> f n :: mapInt f ns
Lists
Simple list
List of integers
Append element to list
Join two lists
Haskell
[0,1,2,3] ++ [4,5,6,7]
List of integers as a function parameter, pattern matching
Function sumList sums all elements of a list
Haskell
sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs
Function parameter infered
F#
let rec sumList = function
| [] -> 0
| (x::xs) -> x + sumList xs
Function parameter explicitly defined
F#
let rec sumList (xs:int list) = match xs with
| [] -> 0
| (x::xs) -> x + sumList xs
List of generic values as a function parameter, option (some, none)
Function hd returns first element of a list, if list is empty returns none
Haskell
hd :: [a] -> Maybe a
hd [] = Nothing
hd xs = Just (head xs)
F#
let hd (xs:’a list) = match xs with
| [] -> None
| (x::xz) -> Some x
List.map
Double numbers in the list
Haskell
map (\\x -> x * 2) [1,2,3,4,5]
F#
List.map (fun x -> x * 2) [1;2;3;4;5]
List.fold_right
Haskell
foldr (\\x y -> x `div` y) 1 [64,8,2]
–– 64 / (8 / (2 / 1)) = 16
F#
List.fold_right (fun x y -> x / y) [64;8;2] 1
// 64 / (8 / (2 / 1)) = 16
List.filter
Get list including only even numbers
Haskell
filter (\\x -> x % 2 == 0) [1,2,3,4,5,6,7,8]
F#
List.filter (fun n -> n % 2 = 0) [1;2;3;4;5;6;7;8]
Types
Simple type
Haskell
type strList = [string]
F#
type strList = string list
Discriminated union type (multiple contructors)
Binary tree
Haskell
–– definition
data Tree = Node Tree Tree
| Leaf
–– usage
(Node (Node Leaf Leaf) Leaf)
F#
// definition
type Tree =
| Node of Tree * Tree
| Leaf
// usage
Node (Node (Leaf, Leaf), Leaf)
Discriminated union type in pattern matching
Function leafCount returns number of leafs in the tree, using Tree type defined in previous example
Haskell
leafCount :: Tree -> Int
leafCount (Node t1 t2)
= leafCount t1 + leafCount t2
leafCount Leaf = 1
F#
let rec leafCount = function
| Node (t1, t2) -> leafCount t1 + leafCount t2
| Leaf -> 1
Discriminated union type with generic value
Binary tree, leafs hold generic values
Haskell
–– definition
data Tree a = Node Tree Tree
| Leaf a
–– usage
(Node (Node (Leaf ‘a’) (Leaf ‘b’)) (Leaf ‘c’))
F#
// definition
type ‘a Tree =
| Node of ‘a Tree * ‘a Tree
| Leaf of ‘a
// usage
Node (Node (Leaf ‘a’, Leaf ‘b’), Leaf ‘c’)
Discriminated union type with generic value
Binary tree, leafs hold list of generic values
Haskell
–– definition
data Tree a = Node Tree Tree
| Leaf [a]
– usage
(Node (Node (Leaf [’a',’b'])
(Leaf [’b',’c'])) (Leaf [’c',’d']))
F#
// definition
type ‘a Tree =
| Node of ‘a Tree * ‘a Tree
| Leaf of (’a list)
// usage
Node (Node (Leaf [’a';’b'], Leaf [’b';’c']),
Leaf [’c';’d'])
Others
Custom operator
Substraction with non-negative result
Haskell
(%%) x y = let res = x - y
in if res > 0 then res else 0
–– 5 %% 2 = 3; 5 %% 8 = 0
F#
let (%%) x y = let res = x - y
in if res > 0 then res else 0
// 5 %% 2 = 3; 5 %% 8 = 0