
Note: Every time you see a delimiter with a file name and a.lhsextension,
You can download it.
If you save the file asfilename.lhs, you can run it with
runhaskell filename.lhs
Some examples may not work, but most should.
Below you should see a link to the file.

ghc : A compiler similar to gcc for Cghci : Haskell interactive shell (REPL)runhaskell : Run the program without compiling it. Convenient, but very slow compared to compiled programs.
main = putStrLn "Hello World!" hello.hs and execute: ~ runhaskell ./hello.hs Hello World! 00_hello_world.lhs file and execute: ~ runhaskell 00_hello_world.lhs Hello World! main = do print " ?" name <- getLine print (" " ++ name ++ "!") # Python print " ?" name = raw_input() print " %s!" % name # Ruby puts " ?" name = gets.chomp puts " #{name}!" // In C #include <stdio.h> int main (int argc, char **argv) { char name[666]; // <- ! // , 665 ? printf(" ?\n"); scanf("%s", name); printf(" %s!\n", name); return 0; } main function is IO () .main creates side effects.
C , C++ or Java , the type system will help you.Calling a function with the same parameters will always give the same result.
>>= , <$> , <- or other scary characters, just ignore them and try to understand the general idea of ββthe code.C : int f(int x, int y) { return x*x + y*y; } function f(x,y) { return x*x + y*y; } def f(x,y): return x*x + y*y def f(x,y) x*x + y*y end (define (fxy) (+ (* xx) (* yy))) fxy = x*x + y*y def . -- :: f :: Int -> Int -> Int fxy = x*x + y*y main = print (f 2 3) ~ runhaskell 20_very_basic.lhs 13 f :: Int -> Int -> Int fxy = x*x + y*y main = print (f 2.3 4.2) 21_very_basic.lhs:6:23: No instance for (Fractional Int) arising from the literal `4.2' Possible fix: add an instance declaration for (Fractional Int) In the second argument of `f', namely `4.2' In the first argument of `print', namely `(f 2.3 4.2)' In the expression: print (f 2.3 4.2) 4.2 is not int.f . fxy = x*x + y*y main = print (f 2.3 4.2) C , you would need to create a function for int , for float , for long , for double , etc. % ghci GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> let fxy = x*x + y*y Prelude> :type f f :: Num a => a -> a -> a Num a => a -> a -> a a -> a -> a .| Specified type | Value |
Int | Int type |
Int -> Int | a function that takes an Int as input and returns an Int |
Float -> Int | function that takes an input Float and returns an Int |
a -> Int | the type of the function that accepts any type of input and returns an Int |
a -> a | the type of the function, which takes type a as input and returns the result of type a |
a -> a -> a | the type of the function that takes two arguments of type a as input and returns the result of type a |
a -> a -> a , the letter a is a type variable .f is a function of two arguments, and both arguments, as well as the result, have the same type.a can take values ββof various types.Int , Integer , Float ...C and separately define functions for int , long , float , double , etc. ...a can be of any type.String , Int , more complex type, such as Trees , type of another function, etc.Num a => .Num is a type class .Num includes only types that behave like numbers.Num is a class containing types that implement a given set of functions, in particular (+) and (*) .Num a => a -> a -> a means:a be a type belonging to the class of types Num .a and returns ( a -> a ).f 3 4 equivalent to (f 3) 4 .f 3 is also a function: f :: Num a :: a -> a -> a g :: Num a :: a -> a g = f 3 gy β 3*3 + y*y g = \y -> 3*3 + y*y \ character is used because it is similar to the Ξ» character, but at the same time it is an ASCII character. f :: Num a => a -> a -> a fxy = x*x + y*y main = print (f 3 2.4) 3 can represent either a Fractional (fractional) number of type Float, or an integer of type Integer.2.4 is of type Fractional, 3 also represented as a Fractional number. f :: Num a => a -> a -> a fxy = x*x + y*y x :: Int x = 3 y :: Float y = 2.4 main = print (fxy) -- , x β y 
β to show the equivalence of two expressions.β symbol will be used to show the result of evaluating an expression. 3 + 2 * 6 / 3 β 3 + ((2*6)/3) True || False β True True && False β False True == False β False True /= False β True (/=) x^n n (Int Integer) x**y y ( Float) Integer not limited in size, except for the memory of the machine: 4^103 102844034832575377634685573909834406561420991602098741459288064 Data.Ratio module: $ ghci .... Prelude> :m Data.Ratio Data.Ratio> (11 % 15) * (5 % 3) 11 % 9 [] β [1,2,3] β ["foo","bar","baz"] β (String) 1:[2,3] β [1,2,3], (:) 1:2:[] β [1,2] [1,2] ++ [3,4] β [1,2,3,4], (++) [1,2,3] ++ ["foo"] β String β Integral [1..4] β [1,2,3,4] [1,3..10] β [1,3,5,7,9] [2,3,5,7,11..100] β ! ! [10,9..1] β [10,9,8,7,6,5,4,3,2,1] Char . 'a' :: Char "a" :: [Char] "" β [] "ab" β ['a','b'] β 'a':"b" β 'a':['b'] β 'a':'b':[] "abc" β "ab"++"c" Note :
In real-world tasks, you will not use a list of characters for working with text.
In most cases,Data.Textused for this.
If you need to work with a stream of ASCII characters, you should useData.ByteString.
(a,b) . -- - (2,"foo") (3,'a',[2,3]) ((2,"a"),"c",3) fst (x,y) β x snd (x,y) β y fst (x,y,z) β ERROR: fst :: (a,b) -> a snd (x,y,z) β ERROR: snd :: (a,b) -> b ($) and (.) . -- : fghx β (((fg) h) x) -- $ $ -- fg $ hx β fg (hx) β (fg) (hx) f $ ghx β f (ghx) β f ((gh) x) f $ g $ hx β f (g (hx)) -- (.) (f . g) x β f (gx) (f . g . h) x β f (g (hx)) x :: Int β x Int x :: a β x x :: Num a => a β x a, Num f :: a -> b β f a b f :: a -> b -> c β f , a (bβc) f :: (a -> b) -> c β f , (aβb) c square :: Num a => a -> a square x = x^2 ^ used in infix notation. square' x = (^) x 2 square'' x = (^2) x x from the left and right side of the expression! square''' = (^2) ' in the function name.squareβsquare'βsquare''βsquare '''
absolute :: (Ord a, Num a) => a -> a absolute x = if x >= 0 then x else -x if .. then .. else in Haskell is more like an operatorΒ€?Β€:Β€ in C. You cannot omit else . absolute' x | x >= 0 = x | otherwise = -x Warning: alignment is important in Haskell programs.
As in Python, incorrect alignment can break the code!

Having a list of integers, you must calculate the sum of even numbers in the list.
example:[1,2,3,4,5] β 2 + 4 β 6
function evenSum(list) { var result = 0; for (var i=0; i< list.length ; i++) { if (list[i] % 2 ==0) { result += list[i]; } } return result; } Note :
Recursion in imperative languages ββhas a reputation as a slow tool. But for most functional languages ββthis is not the case. In most cases, Haskell optimizes work with recursive functions in a very high quality.
C For simple, I assume that the list of numbers ends with a null value. int evenSum(int *list) { return accumSum(0,list); } int accumSum(int n, int *list) { int x; int *xs; if (*list == 0) { // if the list is empty return n; } else { x = list[0]; // let x be the first element of the list xs = list+1; // let xs be the list without x if ( 0 == (x%2) ) { // if x is even return accumSum(n+x, xs); } else { return accumSum(n, xs); } } } even :: Integral a => a -> Bool head :: [a] -> a tail :: [a] -> [a] even parity check. even :: Integral a => a -> Bool even 3 β False even 2 β True head returns the first item in the list: head :: [a] -> a head [1,2,3] β 1 head [] β ERROR tail returns all list items, except for the first: tail :: [a] -> [a] tail [1,2,3] β [2,3] tail [3] β [] tail [] β ERROR l ,l β (head l):(tail l)evenSum function returns the sum of all even numbers in the list: -- 1 evenSum :: [Integer] -> Integer evenSum l = accumSum 0 l accumSum nl = if l == [] then n else let x = head l xs = tail l in if even x then accumSum (n+x) xs else accumSum n xs ghci : % ghci GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> :load 11_Functions.lhs [1 of 1] Compiling Main ( 11_Functions.lhs, interpreted ) Ok, modules loaded: Main. *Main> evenSum [1..5] 6 *Main> evenSum [1..5] accumSum 0 [1,2,3,4,5] 1 is odd accumSum 0 [2,3,4,5] 2 is even accumSum (0+2) [3,4,5] 3 is odd accumSum (0+2) [4,5] 4 is even accumSum (0+2+4) [5] 5 is odd accumSum (0+2+4) [] l == [] 0+2+4 0+6 6 evenSum :: Integral a => [a] -> a where or let .accumSum function accumSum not pollute the global namespace. -- 2 evenSum :: Integral a => [a] -> a evenSum l = accumSum 0 l where accumSum nl = if l == [] then n else let x = head l xs = tail l in if even x then accumSum (n+x) xs else accumSum n xs -- 3 evenSum l = accumSum 0 l where accumSum n [] = n accumSum n (x:xs) = if even x then accumSum (n+x) xs else accumSum n xs foo l = if l == [] then <x> else <y> foo [] = <x> foo l = <y> foo l = let x = head l xs = tail l in if even x then foo (n+x) xs else foo n xs foo (x:xs) = if even x then foo (n+x) xs else foo n xs fx = (- ) x f = - l : -- 4 evenSum :: Integral a => [a] -> a evenSum = accumSum 0 where accumSum n [] = n accumSum n (x:xs) = if even x then accumSum (n+x) xs else accumSum n xs 
filter :: (a -> Bool) -> [a] -> [a] map :: (a -> b) -> [a] -> [b] foldl :: (a -> b -> a) -> a -> [b] -> a -- 5 evenSum l = mysum 0 (filter even l) where mysum n [] = n mysum n (x:xs) = mysum (n+x) xs filter even [1..10] β [2,4,6,8,10] filter function accepts a function of type ( a -> Bool ) and a list of type [a] as arguments. It returns a list containing only those elements for which the function returned true .foldl function, which allows you to accumulate a value. The foldl function implements a popular programming technique: myfunc list = foo initialValue list foo accumulated [] = accumulated foo tmpValue (x:xs) = foo (bar tmpValue x) xs myfunc list = foldl bar initialValue list foldl shown below. foldl fz [] = z foldl fz (x:xs) = foldl f (fzx) xs foldl fz [x1,...xn] β f (... (f (fz x1) x2) ...) xn (fzx) , but pushes it (fzx) stack.foldl' instead of foldl ;foldl' is a strict (or energetic) implementation of foldl .evenSum looks like this: -- 6 -- foldl' -- Data.List import Data.List evenSum l = foldl' mysum 0 (filter even l) where mysum acc value = acc + value mysum . -- 7 -- -- import Data.List (foldl') evenSum l = foldl' (\xy -> x+y) 0 (filter even l) (\xy -> x+y) β (+) -- 8 import Data.List (foldl') evenSum :: Integral a => [a] -> a evenSum l = foldl' (+) 0 (filter even l) foldl' not the most intuitive feature. But with her, you should definitely figure it out. evenSum [1,2,3,4] β foldl' (+) 0 (filter even [1,2,3,4]) β foldl' (+) 0 [2,4] β foldl' (+) (0+2) [4] β foldl' (+) 2 [4] β foldl' (+) (2+4) [] β foldl' (+) 6 [] β 6 (.) .(.) . (f . g . h) x β f ( g (hx)) -- 9 import Data.List (foldl') evenSum :: Integral a => [a] -> a evenSum = (foldl' (+) 0) . (filter even) -- 10 import Data.List (foldl') sum' :: (Num a) => [a] -> a sum' = foldl' (+) 0 evenSum :: Integral a => [a] -> a evenSum = sum' . (filter even) [1,2,3,4] β· [1,4,9,16] β· [4,16] β· 20 squareEvenSum = sum' . (filter even) . (map (^2)) squareEvenSum' = evenSum . (map (^2)) squareEvenSum'' = sum' . (map (^2)) . (filter even) squareEvenSum'' . (.) .). map (^2) [1,2,3,4] β [1,4,9,16] map - .
tl;dr :
type Name = AnotherType,NameAnotherType.data Name = NameConstructor AnotherType.data.deriving.
square Haskell: square x = x * x square ( ) Numeral.Int , Integer , Float , Fractional Complex . For example: % ghci GHCi, version 7.0.4: ... Prelude> let square x = x*x Prelude> square 2 4 Prelude> square 2.1 4.41 Prelude> -- Data.Complex Prelude> :m Data.Complex Prelude Data.Complex> square (2 :+ 1) 3.0 :+ 4.0 x :+ y ( x + iy ). int int_square(int x) { return x*x; } float float_square(float x) {return x*x; } complex complex_square (complex z) { complex tmp; tmp.real = z.real * z.real - z.img * z.img; tmp.img = 2 * z.img * z.real; } complex x,y; y = complex_square(x); #include <iostream> #include <complex> using namespace std; template<typename T> T square(T x) { return x*x; } int main() { // int int sqr_of_five = square(5); cout << sqr_of_five << endl; // double cout << (double)square(5.3) << endl; // complex cout << square( complex<double>(5,3) ) << endl; return 0; } β , β
type Name = String type Color = String showInfos :: Name -> Color -> String showInfos name color = "Name: " ++ name ++ ", Color: " ++ color name :: Name name = "Robin" color :: Color color = "Blue" main = putStrLn $ showInfos name color showInfos : putStrLn $ showInfos color name data . data Name = NameConstr String data Color = ColorConstr String showInfos :: Name -> Color -> String showInfos (NameConstr name) (ColorConstr color) = "Name: " ++ name ++ ", Color: " ++ color name = NameConstr "Robin" color = ColorConstr "Blue" main = putStrLn $ showInfos name color showInfos , . . . NameConstr :: String -> Name ColorConstr :: String -> Color data : data TypeName = ConstructorName [types] | ConstructorName2 [types] | ... data Complex = Num a => Complex aa data DataTypeName = DataConstructor { field1 :: [type of field1] , field2 :: [type of field2] ... , fieldn :: [type of fieldn] } data Complex = Num a => Complex { real :: a, img :: a} c = Complex 1.0 2.0 z = Complex { real = 3, img = 4 } real c β 1.0 img z β 4 data List a = Empty | Cons a (List a) infixr 5 ::: data List a = Nil | a ::: (List a) infixr β .Show ), ( Read ), ( Eq ) ( Ord ) , Haskell-, . infixr 5 ::: data List a = Nil | a ::: (List a) deriving (Show,Read,Eq,Ord) deriving (Show) , Haskell show . , show . convertList [] = Nil convertList (x:xs) = x ::: convertList xs main = do print (0 ::: 1 ::: Nil) print (convertList [0,1]) 0 ::: (1 ::: Nil) 0 ::: (1 ::: Nil) 
import Data.List data BinTree a = Empty | Node a (BinTree a) (BinTree a) deriving (Show) treeFromList :: (Ord a) => [a] -> BinTree a treeFromList [] = Empty treeFromList (x:xs) = Node x (treeFromList (filter (<x) xs)) (treeFromList (filter (>x) xs)) (x:xs) , :xxs xxs x . main = print $ treeFromList [7,2,4,8] Node 7 (Node 2 Empty (Node 4 Empty Empty)) (Node 8 Empty Empty) deriving (Show) BinTree . BinTree ( Eq Ord ). . data BinTree a = Empty | Node a (BinTree a) (BinTree a) deriving (Eq,Ord) deriving (Show) , Haskell show .show . , , BinTree aShow . instance Show (BinTree a) where show t = ... -- -- BinTree Show instance (Show a) => Show (BinTree a) where -- '<' -- : show t = "< " ++ replace '\n' "\n: " (treeshow "" t) where -- treeshow pref Tree -- pref -- treeshow pref Empty = "" -- Leaf treeshow pref (Node x Empty Empty) = (pshow pref x) -- treeshow pref (Node x left Empty) = (pshow pref x) ++ "\n" ++ (showSon pref "`--" " " left) -- treeshow pref (Node x Empty right) = (pshow pref x) ++ "\n" ++ (showSon pref "`--" " " right) -- treeshow pref (Node x left right) = (pshow pref x) ++ "\n" ++ (showSon pref "|--" "| " left) ++ "\n" ++ (showSon pref "`--" " " right) -- showSon pref before next t = pref ++ before ++ treeshow (pref ++ next) t -- pshow "\n" "\n"++pref pshow pref x = replace '\n' ("\n"++pref) (show x) -- replace c new string = concatMap (change c new) string where change c new x | x == c = new | otherwise = x:[] -- "x" treeFromList . treeFromList :: (Ord a) => [a] -> BinTree a treeFromList [] = Empty treeFromList (x:xs) = Node x (treeFromList (filter (<x) xs)) (treeFromList (filter (>x) xs)) main = do putStrLn "Int binary tree:" print $ treeFromList [7,2,4,8,1,3,6,21,12,23] print $ treeFromList [7,2,4,8,1,3,6,21,12,23] Int binary tree: < 7 : |--2 : | |--1 : | `--4 : | |--3 : | `--6 : `--8 : `--21 : |--12 : `--23 < . : . putStrLn "\nString binary tree:" print $ treeFromList ["foo","bar","baz","gor","yog"] String binary tree: < "foo" : |--"bar" : | `--"baz" : `--"gor" : `--"yog" putStrLn "\n :" print ( treeFromList (map treeFromList ["baz","zara","bar"])) : < < 'b' : : |--'a' : : `--'z' : |--< 'b' : | : |--'a' : | : `--'r' : `--< 'z' : : `--'a' : : `--'r' : .
putStrLn "\nTree of Binary trees of Char binary trees:" print $ (treeFromList . map (treeFromList . map treeFromList)) [ ["YO","DAWG"] , ["I","HEARD"] , ["I","HEARD"] , ["YOU","LIKE","TREES"] ] print ( treeFromList ( map treeFromList [ map treeFromList ["YO","DAWG"] , map treeFromList ["I","HEARD"] , map treeFromList ["I","HEARD"] , map treeFromList ["YOU","LIKE","TREES"] ])) Binary tree of Binary trees of Char binary trees: < < < 'Y' : : : `--'O' : : `--< 'D' : : : |--'A' : : : `--'W' : : : `--'G' : |--< < 'I' : | : `--< 'H' : | : : |--'E' : | : : | `--'A' : | : : | `--'D' : | : : `--'R' : `--< < 'Y' : : : `--'O' : : : `--'U' : : `--< 'L' : : : `--'I' : : : |--'E' : : : `--'K' : : `--< 'T' : : : `--'R' : : : |--'E' : : : `--'S' "I","HEARD" . () , Tree Eq .
( ) .(a+(b*c)),+,(b*c)
-- numbers = [1,2,..] numbers :: [Integer] numbers = 0:map (1+) numbers take' n [] = [] take' 0 l = [] take' n (x:xs) = x:take' (n-1) xs main = print $ take' 10 numbers , . [1..] β [1,2,3,4...] [1,3..] β [1,3,5,7,9,11...] take take' . nullTree = Node 0 nullTree nullTree -- BinTree -- treeTakeDepth _ Empty = Empty treeTakeDepth 0 _ = Empty treeTakeDepth n (Node x left right) = let nl = treeTakeDepth (n-1) left nr = treeTakeDepth (n-1) right in Node x nl nr main = print $ treeTakeDepth 4 nullTree < 0 : |-- 0 : | |-- 0 : | | |-- 0 : | | `-- 0 : | `-- 0 : | |-- 0 : | `-- 0 : `-- 0 : |-- 0 : | |-- 0 : | `-- 0 : `-- 0 : |-- 0 : `-- 0 iTree = Node 0 (dec iTree) (inc iTree) where dec (Node xlr) = Node (x-1) (dec l) (dec r) inc (Node xlr) = Node (x+1) (inc l) (inc r) map , BinTree . -- Tree treeMap :: (a -> b) -> BinTree a -> BinTree b treeMap f Empty = Empty treeMap f (Node x left right) = Node (fx) (treeMap f left) (treeMap f right) map , functor() fmap . infTreeTwo :: BinTree Int infTreeTwo = Node 0 (treeMap (\x -> x-1) infTreeTwo) (treeMap (\x -> x+1) infTreeTwo) main = print $ treeTakeDepth 4 infTreeTwo < 0 : |-- -1 : | |-- -2 : | | |-- -3 : | | `-- -1 : | `-- 0 : | |-- -1 : | `-- 1 : `-- 1 : |-- 0 : | |-- -1 : | `-- 1 : `-- 2 : |-- 1 : `-- 3 Source: https://habr.com/ru/post/152889/
All Articles