
P provability of the statement “if provable P , then P true” is possible only in the case of provability of the statement P .
loeb is one of those functions on Haskele that looks charming, crazy, simple and complex at the same time.loeb function: loeb :: Functor f => f (fa -> a) -> fa loeb x = go where go = fmap ($ go) x loeb :: Functor f => f (fa -> a) -> fa :: , then we’ll write restrictions on the parameters to the fat arrow ( => ) - I’ll explain it a little bit below until it matters. And finally - the types themselves:f (fa -> a) -> fa , look how close the record is to the Loeb theorem:
- yes one to one! loeb :: Functor f => f (fa -> a) -> fa loeb x = go where go = fmap ($ go) x where is a service one and makes it possible to define an internal function.f (x, y, z) = ... , in Haskell they write only fxyz = ...loeb function is a function of one argument and it is determined through the function go .go defined by the Functor and the function fmap . The fmap function itself is a generalization of the map function for lists and is defined as follows: class Functor f where fmap :: (a -> b) -> fa -> fb f will be polymorphic in the function fmap .fmap is a function of two arguments - (a -> b) and fa , the output is type fb .(a -> b) is a function of one argument, taking some value as an input (generally we call this type a , it can be any — for example, a string, a number, or a file) and the output is also some or a type (we denote it by b , remembering that b in particular may be a ).fa - can be understood as a kind of complex value depending on a and it will be easier to understand if you read as f(a)fmap applies the function to the value through f , and, as a rule, it is so. instance Functor [] where fmap = map fmap function fmap completely analogous to the map function. Well, the map function already all imperatives know, this application of the function to all the members of the list. In Haskell, it is determined very simply: map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:xs) = fx : map f xs x : xs , notice the letter s , in English, this means the plural, they say many x -s in xs ) and return another list, where we use the function for the head, and tail we recursively apply our described function.map function map , but do not fully understand how fmap = map can be done - everything is quite simple, replace f with [] fmap :: (a -> b) -> [] a -> [] b fmap :: (a -> b) -> [a] -> [b] go = fmap ($ go) x $ Is an ordinary function-operator, called an applicative function and is determined elementarily: ($) :: (a -> b) -> a -> b f $ x = fx loeb function using lambda expressions: loeb :: Functor f => f (fa -> a) -> fa loeb x = go where go = fmap (\z -> z go) x \z -> z go means that the lambda function (a slash resembles the Greek letter lambda - λ ) from one variable z , and the arrow -> read like =loeb doing?loeb calculates the result in terms of itself, but this is more crazy than what you felt when you first heard about recursion.loeb use for? Where is it useful? For example, you can make a spreadsheet (like Exel) for a list functor - []: xs :: [a] xs = [...] fs :: [[a] -> a] fs = [...] rs :: [a] rs = [ f xs | f <- fs ] -- r = f xs xs :: [a] . And we have a list of functions that collapse the lists to values, fs :: [[a] -> a] . We take and for each function from the list we apply to the list of elements, thus obtaining a new value r . Collect all r in the list rs . [ f xs | f <- fs ] rs from the list of xs values and the list of fs functions.xs values, and use rs instead. In other words, the function f is applied to the list of results, which itself generates! fs :: [[a] -> a] fs = [...] rs :: [a] rs = [ f rs | f <- fs ] rs is calculated in terms of itself. You can combine both functions to not have your own definitions of fs , and they will be just the rs parameter: rs fs = [ f (rs fs) | f <- fs ] rs = loebloeb function takes a list of functions, and calculates a list of results that it generates, and applies itself to the list just generated. Strange? Check? Ringed? I bet no!loeb fs = [ const 1 , succ . (!! 0) , succ . (!! 1) , succ . (!! 2) ] const a _ = a is a function of two variables, which always returns the value of the first, succ x = inc increment for numbers (more precisely, this is a generalization of the increment for any enumerated values), (!!) is the function of pulling the n element from the list , (.) - functional composition of 2 functions, first applies the right function, then the left one, in our case, first pulls an element from the list, then increments.const 1 we have the first element, and it always returns 1, after that you can get the value of the second element - succ . (!! 0) succ . (!! 0) , and further along the chain - the third, fourth and fifth. > loeb fs [1,2,3,4] fs = [ succ . (!! 1) , succ . (!! 3) , succ . (!! 0) , const 1 ] > loeb fs [3,2,4,1] import Data.Array import Data.List import Control.Monad import Text.Printf loeb :: Functor f => f (fa -> a) -> fa loeb x = go where go = fmap ($ go) x -- e = val 0 -- val = const -- , (10 %) vat ix = (* 0.1) . (! ix) -- sum' ixs = \arr -> foldl' (\acc ix -> acc + arr ! ix) 0 ixs spreadsheet = listArray ((0,0), (4,4)) -- Prices | VAT | Effective prices + total [ val 1, vat (0,0), sum' [(0,i) | i <- [0..1]], e, e , val 3, vat (1,0), sum' [(1,i) | i <- [0..1]], e, e , val 5, vat (2,0), sum' [(2,i) | i <- [0..1]], e, e , val 2, vat (3,0), sum' [(3,i) | i <- [0..1]], e, e , e, e, sum' [(i,2) | i <- [0..3]], e, e ] printArr :: Array (Int, Int) Double -> IO () printArr arr = forM_ [0..4] $ \i -> do forM_ [0..4] $ \j -> printf "%4.1f " (arr ! (i,j)) printf "\n" main = printArr $ loeb spreadsheet 1.0 0.1 1.1 0.0 0.0 3.0 0.3 3.3 0.0 0.0 5.0 0.5 5.5 0.0 0.0 2.0 0.2 2.2 0.0 0.0 0.0 0.0 12.1 0.0 0.0 val ), in the second column we have taxes of what is left, in the third column the effective price, and below the total sum of all effective prices. Now you can see, order and buy everything! Magic! :-)moeb functionmoeb is the result of the game with the definition of the loeb function: what if we want to abstract from the fmap . For starters, this will make the signature under the function just crazy! -- [m]oeb = multi-loeb :-) moeb :: (((a -> b) -> b) -> c -> a) -> c -> a moeb fx = go where go = f ($ go) x loeb , it will only be a special case of moeb : loeb = moeb fmap moeb function moeb that it can be used? id :: a -> a id x = x moeb id x = id ($ moeb id x) x = ($ moeb id x) x = x (moeb id x) -- , fix -- fix f = f (fix f) fix = moeb id moeb is a generalization of the fix function.moeb parameters, such as traverse and foldMap , but I still don’t know why you can use it for something useful.Source: https://habr.com/ru/post/203800/
All Articles