Haskell – 122 – altre monadi ancora – 3

Continuo da qui, copio qui, scrollare fino a “The Writer type”.

Il tipo Writer
Now that we’ve seen that a value with an attached monoid acts like a monadic value, let’s examine the Monad instance for types of such values. The Control.Monad.Writer module exports the Writer w a type along with its Monad instance and some useful functions for dealing with values of this type.

First, let’s examine the type itself. To attach a monoid to a value, we just need to put them together in a tuple. The Writer w a type is just a newtype wrapper for this. Its definition is very simple:

newtype Writer w a = Writer { runWriter :: (a, w) }

It’s wrapped in a newtype so that it can be made an instance of Monad and that its type is separate from a normal tuple. The a type parameter represents the type of the value and the w type parameter the type of the attached monoid value.

Its Monad instance is defined like so:

instance (Monoid w) => Monad (Writer w) where
  return x = Writer (x, mempty)
  (Writer (x,v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v')

First off, let’s examine >>=. Its implementation is essentially the same as applyLog, only now that our tuple is wrapped in the Writer newtype, we have to unwrap it when pattern matching. We take the value x and apply the function f to it. This gives us a Writer w a value and we use a let expression to pattern match on it. We present y as the new result and use mappend to combine the old monoid value with the new one. We pack that up with the result value in a tuple and then wrap that with the Writer constructor so that our result is a Writer value instead of just an unwrapped tuple.

So, what about return? It has to take a value and put it in a default minimal context that still presents that value as the result. So what would such a context be for Writer values? If we want the accompanying monoid value to affect other monoid values as little as possible, it makes sense to use mempty. mempty is used to present identity monoid values, such as "" and Sum 0 and empty bytestrings. Whenever we use mappend between mempty and some other monoid value, the result is that other monoid value. So if we use return to make a Writer value and then use >>= to feed that value to a function, the resulting monoid value will be only what the function returns. Let’s use return on the number 3 a bunch of times, only we’ll pair it with a different monoid every time:

Prelude> :set prompt "ghci> "
ghci> import Control.Monad.Writer
ghci> runWriter (return 3 :: Writer String Int)
(3,"")
ghci> runWriter (return 3 :: Writer (Sum Int) Int)
(3,Sum {getSum = 0})
ghci> runWriter (return 3 :: Writer (Product Int) Int)
(3,Product {getProduct = 1})

Because Writer doesn’t have a Show instance, we had to use runWriter to convert our Writer values to normal tuples that can be shown. For String, the monoid value is the empty string. With Sum, it’s 0, because if we add 0 to something, that something stays the same. For Product, the identity is 1.

The Writer instance doesn’t feature an implementation for fail, so if a pattern match fails in do notation, error is called.

Usare  do notationc con writer
Now that we have a Monad instance, we’re free to use do notation for Writer values. It’s handy for when we have a several Writer values and we want to do stuff with them. Like with other monads, we can treat them as normal values and the context gets taken for us. In this case, all the monoid values that come attached get mappended and so are reflected in the final result. Here’s a simple example of using do notation with Writer to multiply two numbers:

Qui c’è un problema, noto. La versione riportata da Miran è vecchia e non più supportata. Lo sa anche Miran che aggiorna, qui. Basta cambiare l’import, quello corretto è Control.Monad.Writer invece del vecchio Control.Monad.

mwl.hs

import Control.Monad.Writer

logNumber :: Int -> Writer [String] Int
logNumber x = writer (x, ["Got number: " ++ show x])

multWithLog :: Writer [String] Int
multWithLog = do
  a <- logNumber 3
  b <- logNumber 5
  return (a*b)

logNumber takes a number and makes a Writer value out of it. For the monoid, we use a list of strings and we equip the number with a singleton list that just says that we have that number. multWithLog is a Writer value which multiplies 3 and 5 and makes sure that their attached logs get included in the final log. We use return to present a*b as the result. Because return just takes something and puts it in a minimal context, we can be sure that it won’t add anything to the log. Here’s what we see if we run this:

Prelude> :l mwl
[1 of 1] Compiling Main             ( mwl.hs, interpreted )
Ok, modules loaded: Main.
*Main> multWithLog
WriterT (Identity (15,["Got number: 3","Got number: 5"]))

Sometimes we just want some monoid value to be included at some particular point. For this, the tell function is useful. It’s part of the MonadWriter type class and in the case of Writer it takes a monoid value, like ["This is going on"] and creates a Writer value that presents the dummy value () as its result but has our desired monoid value attached. When we have a monadic value that has () as its result, we don’t bind it to a variable. Here’s multWithLog but with some extra reporting included:

multWithLog :: Writer [String] Int
multWithLog = do
  a <- logNumber 3
  b <- logNumber 5
  tell ["Gonna multiply these two"]
  return (a*b)

It’s important that return (a*b) is the last line, because the result of the last line in a do expression is the result of the whole do expression. Had we put tell as the last line, () would have been the result of this do expression. We’d lose the result of the multiplication. However, the log would be the same. Here is this in action:

*Main> runWriter multWithLog
(15,["Got number: 3","Got number: 5"])

Pausa, devo recuperare per l’errore di aggiornamento 😐

👽

Annunci

Numeri grossi –troppo!

Una scorsa ai linguaggi –non di sistema— per un presunto problema, quello evidenziato qui.

Uh! verifiche, prima di subito! 💥

bc
Anticamente, quando il  mondo  Unix era giovane si usava bc; OK, prima ancora c’era dc ma –come dire…

* bigN $ bc -l
a = 57055^3
b = 339590^3
c = 340126^3
a + b
39347712995520375
c
39347712995520376
(a + b) == c
0

OK, al solito per i valori booleani false viene rappresentato da 0.

Calc
Ma l’evoluzione… bc è sempre OK, ce l’ho nel mio toolbox ma normalmente per queste elaborazioni volanti uso Calc.

* bigN $ calc -d
; a = 57055**3
; b = 339590**3
; c = 340126**3
; a + b
	39347712995520375
; c
	39347712995520376
; (a + b) == c
	0

Python
Abitualmente sono pythonista

* bigN $ python3 -q
>>> a = 57055**3
>>> b = 339590**3
>>> c = 340126**3
>>> a + b
39347712995520375
>>> c
39347712995520376
>>> (a + b) == c
False

Racket
Quando posso (cioè è solo per me, nessuno che poi mi urla dietro) faccio così:

* bigN $ racket
Welcome to Racket v6.9.
> (define a (expt 57055 3))
> (define b (expt 339590 3))
> (define c (expt 340126 3))
> (+ a b)
39347712995520375
> c
39347712995520376
> (= (+ a b) c)
#f

newLISP
Un Lisp ruspante, piccolo, veloce –posso dire quirkxotico?– che amo da sempre.

> (set 'a (pow 57055 3))
185729602441375
> (set 'b (pow 339590 3))
3,9161983393079e+16
> (set 'c (pow 340126 3))
3,934771299552038e+16
> (+ a b)
39347712995520375
> (- c (+ a b))
1
> (= c (+ a b))
true

Ahemmm… no! vede che c’è la differenza di 1 ma la comparazione con = da true.

Ma sono io che sto sbagliando! Leggi il manuale! (cit.) 👿

> (set 'a (pow (bigint 57055) 3))
185729602441375
> (set 'b (pow (bigint 339590) 3))
3,9161983393079e+16
> (set 'c (pow (bigint 340126) 3))
3,934771299552038e+16
> (+ a b)
39347712995520375
> (= c (+ a b))
true
> (zero? (- c (+ a b)))
nil
> (- c (+ a b))
1

Non funziona la funzione = (che però si può facilmente ridefinire) ma i calcoli sono corretti.

Posso non provare SmallTalk? devo vero? Ecco:

* bigN $ gst
GNU Smalltalk ready

st> a := 57055 raisedToInteger: 3.
185729602441375
st> b := 339590 raisedToInteger: 3.
39161983393079000
st> c := 340126 raisedToInteger: 3.
39347712995520376
st> a + b
39347712995520375
st> (a + b) == c
false

Foglio di calcolo, tipo Excel
C’è anche chi… OK, provo. Non posso copiare come vorrei (come fatto finora) il testo, metto lo screenshot.
Personalmente: detesto la sintassi tutta sua, ma forse basta abituarsi.

Ah! ero partito da qui, mica l’ho dimenticato.

JavaScript

st> * bigN $ node
> a = Math.pow(57055, 3)
185729602441375
> b = Math.pow(339590, 3)
39161983393079000
> c = Math.pow(340126, 3)
39347712995520376
> (a + b) == c
true
> (a + b) - c
0

No!, sbaglia anche la sottrazione.

Insomma solo i linguaggi che supportano la precisione arbitraria per gli interi sono matematicamente corretti.

In pratica serve tutta questa precisione? Dipende, ma in genere no.

Mi dicono, ma non ho verificato, che anche per JavaScript esiste un modulo ad hoc.

Gli altri linguaggi? Sì, per esempio Julia, Ruby e Lua, c’è per tutti tre. Si potrebbe provarli ma credo basti. O no? 😐

👽

Haskell – 121 – altre monadi ancora – 2

Continuo da qui, copio qui.

Piccolo problema: Miran insiste con la metafora che io ho ranzato via; ma chissene… 😎

Writer, difficile conoscerla
We’ve loaded our gun with the Maybe monad, the list monad and the IO monad. Now let’s put the Writer monad in the chamber and see what happens when we fire it!

Whereas Maybe is for values with an added context of failure and the list is for non-deterministic values, the Writer monad is for values that have another value attached that acts as a sort of log value. Writer allows us to do computations while making sure that all the log values are combined into one log value that then gets attached to the result.

For instance, we might want to equip our values with strings that explain what’s going on, probably for debugging purposes. Consider a function that takes a number of bandits in a gang and tells us if that’s a big gang or not. That’s a very simple function:

isBigGang :: Int -> Bool
isBigGang x = x > 9

Now, what if instead of just giving us a True or False value, we want it to also return a log string that says what it did? Well, we just make that string and return it along side our Bool:

ibg.hs

isBigGang :: Int -> (Bool, String)
isBigGang x = (x > 9, "Compared gang size to 9.")

So now instead of just returning a Bool, we return a tuple where the first component of the tuple is the actual value and the second component is the string that accompanies that value. There’s some added context to our value now. Let’s give this a go:

Prelude> :l ibg
[1 of 1] Compiling Main             ( ibg.hs, interpreted )
Ok, modules loaded: Main.
*Main> isBigGang 3
(False,"Compared gang size to 9.")
*Main> isBigGang 30
(True,"Compared gang size to 9.")

So far so good. isBigGang takes a normal value and returns a value with a context. As we’ve just seen, feeding it a normal value is not a problem. Now what if we already have a value that has a log string attached to it, such as (3, "Smallish gang."), and we want to feed it to isBigGang? It seems like once again, we’re faced with this question: if we have a function that takes a normal value and returns a value with a context, how do we take a value with a context and feed it to the function?

When we were exploring the Maybe monad, we made a function applyMaybe, which took a Maybe a value and a function of type a -> Maybe b and fed that Maybe a value into the function, even though the function takes a normal a instead of a Maybe a. It did this by minding the context that comes with Maybe a values, which is that they are values with possible failure. But inside the a -> Maybe b function, we were able to treat that value as just a normal value, because applyMaybe (which later became >>=) took care of checking if it was a Nothing or a Just value.

In the same vein, let’s make a function that takes a value with an attached log, that is, an (a,String) value and a function of type a -> (b,String) and feeds that value into the function. We’ll call it applyLog. But because an (a,String) value doesn’t carry with it a context of possible failure, but rather a context of an additional log value, applyLog is going to make sure that the log of the original value isn’t lost, but is joined together with the log of the value that results from the function. Here’s the implementation of applyLog:

al.hs

isBigGang :: Int -> (Bool, String)
isBigGang x = (x > 9, "Compared gang size to 9.")

applyLog :: (a,String) -> (a -> (b,String)) -> (b,String)
applyLog (x,log) f = let (y,newLog) = f x in (y,log ++ newLog)

When we have a value with a context and we want to feed it to a function, we usually try to separate the actual value from the context and then try to apply the function to the value and then see that the context is taken care of. In the Maybe monad, we checked if the value was a Just x and if it was, we took that x and applied the function to it. In this case, it’s very easy to find the actual value, because we’re dealing with a pair where one component is the value and the other a log. So first we just take the value, which is x and we apply the function f to it. We get a pair of (y,newLog), where y is the new result and newLog the new log. But if we returned that as the result, the old log value wouldn’t be included in the result, so we return a pair of (y,log ++ newLog). We use ++ to append the new log to the old one.

Here’s applyLog in action:

*Main> :l al
[1 of 1] Compiling Main             ( al.hs, interpreted )
Ok, modules loaded: Main.
*Main> (3, "Smallish gang.") `applyLog` isBigGang
(False,"Smallish gang.Compared gang size to 9.")
*Main> (30, "A freaking platoon.") `applyLog` isBigGang
(True,"A freaking platoon.Compared gang size to 9.")

The results are similar to before, only now the number of people in the gang had its accompanying log and it got included in the result log. Here are a few more examples of using applyLog:

*Main> ("Tobin","Got outlaw name.") `applyLog` (\x -> (length x, "Applied length."))
(5,"Got outlaw name.Applied length.")
*Main> ("Bathcat","Got outlaw name.") `applyLog` (\x -> (length x, "Applied length"))
(7,"Got outlaw name.Applied length")

See how inside the lambda, x is just a normal string and not a tuple and how applyLog takes care of appending the logs.

Monoidi al soccorso
Be sure you know what monoids [qui] are at this point!

Right now, applyLog takes values of type (a,String), but is there a reason that the log has to be a String? It uses ++ to append the logs, so wouldn’t this work on any kind of list, not just a list of characters? Sure it would. We can go ahead and change its type to this:

applyLog :: (a,[c]) -> (a -> (b,[c])) -> (b,[c])

Now, the log is a list. The type of values contained in the list has to be the same for the original list as well as for the list that the function returns, otherwise we wouldn’t be able to use ++ to stick them together.

Would this work for bytestrings? There’s no reason it shouldn’t. However, the type we have now only works for lists. It seems like we’d have to make a separate applyLog for bytestrings. But wait! Both lists and bytestrings are monoids. As such, they are both instances of the Monoid type class, which means that they implement the mappend function. And for both lists and bytestrings, mappend is for appending. Watch:

*Main> import qualified Data.ByteString as B
*Main B> :set prompt "ghci> "
ghci> [1,2,3] `mappend` [4,5,6]
[1,2,3,4,5,6]
ghci> B.pack [99,104,105] `mappend` B.pack [104,117,97,104,117,97]
"chihuahua"

Non è esattamente come dice Miran, chissà se ho fatto l’import corretto?

Cool! Now our applyLog can work for any monoid. We have to change the type to reflect this, as well as the implementation, because we have to change ++ to mappend:

applyLog :: (Monoid m) => (a,m) -> (a -> (b,m)) -> (b,m)
applyLog (x,log) f = let (y,newLog) = f x in (y,log `mappend` newLog)

Because the accompanying value can now be any monoid value, we no longer have to think of the tuple as a value and a log, but now we can think of it as a value with an accompanying monoid value. For instance, we can have a tuple that has an item name and an item price as the monoid value. We just use the Sum newtype to make sure that the prices get added as we operate with the items. Here’s a function that adds drink to some cowboy food:

cb.hs

import Data.Monoid

type Food = String
type Price = Sum Int

addDrink :: Food -> (Food,Price)
addDrink "beans" = ("milk", Sum 25)
addDrink "jerky" = ("whiskey", Sum 99)
addDrink _ = ("beer", Sum 30)

We use strings to represent foods and an Int in a Sum newtype wrapper to keep track of how many cents something costs. Just a reminder, doing mappend with Sum results in the wrapped values getting added together:

ghci> :l cb
[1 of 1] Compiling Main             ( cb.hs, interpreted )
Ok, modules loaded: Main.
ghci> Sum 3 `mappend` Sum 9
Sum {getSum = 12}

The addDrink function is pretty simple. If we’re eating beans, it returns "milk" along with Sum 25, so 25 cents wrapped in Sum. If we’re eating jerky we drink whiskey and if we’re eating anything else we drink beer. Just normally applying this function to a food wouldn’t be terribly interesting right now, but using applyLog to feed a food that comes with a price itself into this function is interesting (devo caricare la nuova definizione di applyLog):

ghci> :l cb1
[1 of 1] Compiling Main             ( cb1.hs, interpreted )
Ok, modules loaded: Main.
ghci> ("beans", Sum 10) `applyLog` addDrink
("milk",Sum {getSum = 35})
ghci> ("jerky", Sum 25) `applyLog` addDrink
("whiskey",Sum {getSum = 124})
ghci> ("dogmeat", Sum 5) `applyLog` addDrink
("beer",Sum {getSum = 35})

Milk costs 25 cents, but if we eat it with beans that cost 10 cents, we’ll end up paying 35 cents. Now it’s clear how the attached value doesn’t always have to be a log, it can be any monoid value and how two such values are combined into one depends on the monoid. When we were doing logs, they got appended, but now, the numbers are being added up.

Because the value that addDrink returns is a tuple of type (Food,Price), we can feed that result to addDrink again, so that it tells us what we should drink along with our drink and how much that will cost us. Let’s give it a shot:

ghci> ("dogmeat", Sum 5) `applyLog` addDrink `applyLog` addDrink
("beer",Sum {getSum = 65})

Adding a drink to some dog meat results in a beer and an additional 30 cents, so ("beer", Sum 35). And if we use applyLog to feed that to addDrink, we get another beer and the result is ("beer", Sum 65).

Pausa che mi sto perdendo 😐

😯

Visto nel Web – 326

Altra rassegna lunga così, manca Povia ma c’è cosa ho wisto nel Web 😋

Focus on the most important terms
#:programming, codice, snippet
::: John D. Cook

WHATIS Going To Happen To WHOIS?
#:Web, Internet
::: Slashdot

Did you know you can optionally use one-based indexing in Python?
leggere tutto il thread
#:linguaggi di programmazione
::: jakevdp ::: jakevdp

Make sure your browsing is encrypted whenever possible. HTTPS Everywhere catches HTTPS that might otherwise slip through the cracks
#:sicurezza, spionaggio, virus
::: EFF

Relational equivalence proofs between imperative and MapReduce algorithms
#:programming, codice, snippet
::: Jose_A_Alonso

Top ten runtime errors from telemetry on thousands of JavaScript projects
#:linguaggi di programmazione
::: yawaramin

Rust Creator Graydon Hoare Says Current Software Development Practices Terrify Him
#:linguaggi di programmazione
::: Slashdot

Reading @mbutterick ‘s “Beautiful Racket”
#:lisp(s) #:manuali, how to
::: TheMichaelBurge

Intro to Low-Level Graphics programming on Linux
#:sistemi operativi
::: b3h3m0th

Dice Minnity che ora più che mai bisogna “intensificare l’attività di monitoraggio dei social network”. Perché Salvini in TV e giornali non ci va mai, sta solo su Twitter
#:caos informativo, fake news, bufale #:censura
::: anonimoconiglio

Gates On a Plane: Alaska Airlines Inflight Entertainment Stars Bill Gates
#:programming, codice, snippet
::: Slashdot

Sailor: A Lua MVC Web Framework
#:linguaggi di programmazione
::: CodelessFuture

ES2018 will include a whole new language
#:linguaggi di programmazione
::: paf31

Can functional programming be liberated from the von Neumann paradigm?
post vecchio ma nuovo per me
#:programmazione funzionale
::: jyothsnasrin

Implementing Sets Efficiently in a Functional Language
#:programmazione funzionale
::: wallingf

LKRG: A Loadable Linux Kernel Module for Runtime Integrity Checking
#:sicurezza, spionaggio, virus
::: Slashdot

Incidentalmente, l’autore del post contro la Boldrini è stato individuato senza bisogno di nuove leggi che limitano la libertà sulla Rete
#:Web, Internet #:censura
::: tigella

Early Facebook and Google Employees Form Coalition to Fight What They Built
#:social media
::: marcelsalathe

Really awesome blog post/tutorial by @dk_jackdaniel on using the #lisp ncurses library CL-CHARMS on basically the best topic you could think of: how to write a backend for McCLIM
#:lisp(s)
::: stylewarning

One of the problems of the whole “static vs dynamic typing” correctness debate is that switching your language is incredibly expensive for a marginal benefit
#:linguaggi di programmazione
::: Hillelogram

The Accelerated Mobile Pages (AMP) Project, affiliated with Google and used by Mada Masr, is the latest platform to be blocked in Egypt, joining a growing list of at least 496 websites blocked by state authorities since May 24, 2017
#:censura
::: MadaMasr

Assemble this game console in four hours
#:hardware
::: lucaciavatta

Block ads on your network with Raspberry Pi and pi-hole
#:hardware #:Web, Internet
::: lucaciavatta

How to check spelling at the Linux command line with Aspell
risulta installato (in Ubuntu) ma da configurare
#:tools, componenti software
::: lucaciavatta

Getting Started with the openbox windows manager in Fedora
uh! anchq questo
#:tools, componenti software
::: lucaciavatta

The Story of Eta: Pure Love & Pure Functional Programming
#:programmazione funzionale
::: rahulmutt

Each franc invested in the ETH Domain generates more than five times its value in Switzerland, and each job creates another five jobs
#:scuola, educazione #:economia
::: marcelsalathe

Don’t underestimate the nerds
::: Daniel Lemire

To be a leader in this company, your job is to find the rose petals in a pile of sh!t
#:protagonisti
::: RichRogersIoT

#Spectre & #Meltdown: So far, the AV-TEST Institute discovered 139 samples which appear to be related to recently reported CPU vulnerabilities.
#:hardware #:bug
::: avtestorg

How To Protect Your Server Against the Meltdown and Spectre Vulnerabilities
#:hardware #:bug
::: daw985

Modem libero: gli operatori non potranno più imporre i loro apparati
#:Web, Internet #:economia
::: vandario

38 of 72 Instant Articles launch partner publications including the New York Times and Washington Post have ditched Facebook’s Instant Articles
#:media #:social media
::: auchenberg

Guide for Regular Expressions in JS
#:linguaggi di programmazione
::: Donearm

Guide to Writing Dockerfiles for Go Web-Apps
#:linguaggi di programmazione
::: Donearm

A compiler that produces executables that are valid ASCII text
non so se è una cosa seria ma eccola
#:linguaggi di programmazione
::: danluu

Seattle Finds Facebook in Violation of City Campaign Finance Law
#:social media
::: Slashdot

Linux Kernel Release Model
#:sistemi operativi
::: b3h3m0th

… which I’ve improved today for you
#:linguaggi di programmazione
::: WebReflection

New Jersey Governor Signs Net Neutrality Order
#:Web, Internet
::: Slashdot

Imagine the day when political operatives can create fake video footage of their enemies. That day is here
#:caos informativo, fake news, bufale
::: nytopinion

Power(Shell) to the people
tutta da verificare
#:tools, componenti software
::: lucaciavatta

Implementing an RPN macro in Rust
#:linguaggi di programmazione
::: _wilfredh

Building Slack for the Linux community and adopting snaps
#:tools, componenti software
::: lucaciavatta

Major study on Americans’ attitudes toward media finds deep partisan divides, but majority see “fake news” as a threat
#:media
::: knightfdn

Denunciare i white hat. Che cosa ridicola
#:sicurezza, spionaggio, virus
::: raistolo ::: DavidPuente ::: DavidPuente ::: fabiochiusi ::: DavidPuente ::: DavidPuente ::: fpietrosanti ::: lastknight ::: fpietrosanti ::: cmnit ::: stevedeft ::: DavidPuente ::: DavidPuente ::: arcangeloroc ::: caludio ::: cmnit ::: discordoconme ::: TomsHWItalia ::: rfc1459 ::: fpietrosanti ::: DavidPuente ::: janavel7 ::: gignico

Restored IBM 1401 compiles and runs FORTRAN II program. 63-pass compiler loads from tape, program reads from cards. It works!
ancora più vecchio di me!
#:storia
::: DoctorFortran

Apple Is Seeing ‘Strong Demand’ For Replacement iPhone Batteries
#:dispositivi mobili
::: Slashdot

We’ve made so that any repl on @replit can talk to the internet, call APIs… and pretty soon open a port and start a server. 🙀
#:linguaggi di programmazione
::: amasad

in case you’d like to test jsc (JavaScriptCore) in macOS or Linux (GNOME)
#:linguaggi di programmazione
::: WebReflection

how the whole NodeJS and modules story should be solved
#:linguaggi di programmazione
::: WebReflection

Chi controlla il device diviene gatekeeper dell’intermediazione che con quel device si fa
#:ditte #:economia
::: quinta

TIL there’s a fizzbuzz equivalent for computer science: “the rainfall problem”
non ho capito bene quale sia la difficoltà; e il tappo -999 si usava ovunque ai miei tempi 😐
#:programming, codice, snippet
::: _wilfredh

we’ll try to make NodeJS modules right, let’s hope it will work!
#:linguaggi di programmazione
::: WebReflection

Query the unicode character database from your terminal
io ho la mia versione personale autocostruita, funziona benissimo
#:programming, codice, snippet
::: climagic

si avvicina o no?

My lecture notes for today close with a footnote, which ends “lambda is the ultimate goto”
piuttosto filosofico, imho
#:programming, codice, snippet
::: wallingf

Facebook is Talking About Expanding Its TV-like Service, Watch, Into a Rival To YouTube
#:Web, Internet
::: slashdot

Missing Microsoft Office? Try SoftMaker Office 2018 for Linux
ma c’è già Libre Office che va alla grande, anche su Windows
#:tools, componenti software
::: dcavedon

Facebook Hired a Full-Time Pollster To Monitor Zuckerberg’s Approval Ratings
#:ditte
::: Slashdot

Fake News Sharing In US Is a Rightwing Thing, Says Oxford Study
#:caos informativo, fake news, bufale
::: Slashdot

Eloquent JavaScript 3rd Edition Draft
#:linguaggi di programmazione #:manuali, how to
::: Donearm

23 open source audio-visual production tools
#:tools, componenti software
::: lucaciavatta

I just released Eve 0.7.7 with a fix to GeoJSON queries
#:linguaggi di programmazione
::: nicolaiarocci

Non è vero che le fake news rischiano di condizionare il voto, come sostiene @LaStampa
#:caos informativo, fake news, bufale
::: valigiablu

Study finds Facebook may have developed a highly effective tool for weeding out false or deliberately misleading content
#:caos informativo, fake news, bufale
::: politico

If Mark gives a speech and he’s talking about immigration and universal health care and access to equal education
#:protagonisti
::: fabiochiusi

Google Search updates hotel lookup features and integrates into Flights
#:Web, Internet
::: 9to5Google

One publisher went ‘cold Turkey’ on FB for a fortnight with some interesting insights
#:social media
::: markfrankel29

Car Hacker’s Handbook
#:open source
::: x0rz

Scusate per il ritardo, ecco i mandanti
usate il link alternativo, come precisato
#:sicurezza, spionaggio, virus
::: r0gue_0 ::: r0gue_0

We just released our official @Microsoft Writing Style Guide
#:manuali, how to
::: docsmsft

Now Google Might Make a Game Console and Game-Streaming Service
#:Web, Internet #:games
::: Slashdot

Overseas publishers of fake news are using Facebook Instant Articles to make their content load faster — and in some cases they use FB’s own ad network to monetize it
#:social media #:caos informativo, fake news, bufale
::: CraigSilverman

Lovely introdution to chaining computations in Haskell
#:linguaggi di programmazione
::: _wilfredh

Bowing To Popularity, Apple Stores In China Accept Alipay
#:ditte
::: Slashdot

I love using this figure from the #sklearn website to explain #machinelearning to students. Illustrates nicely how ML works and how performance varies across diff data sets
#:linguaggi di programmazione
::: moorejh

Why don’t more programming languages let you print functions/closures?
#:programmazione funzionale
::: TheMichaelBurge

I knew it’s also true that a good way to invent the future is to predict it. So I predicted Utopia. John Perry Barlow, RIP.
#:protagonisti
::: fabiochiusi ::: annamasera ::: codinghorror ::: JannaQ ::: FreedomofPress

Windows 10 Will Soon Get Progressive Web Apps To Boost the Microsoft Store
#:Web, Internet
::: Slashdot

Interested in how you could share state and call actions in another tab in a web app? I wrote about how you can do it with Service Workers
#:Web, Internet #:linguaggi di programmazione
::: JamesLMilner

Key iPhone Source Code Gets Posted On GitHub
#:sicurezza, spionaggio, virus
::: Slashdot ::: Slashdot ::: dcavedon ::: Slashdot

Wow, #pythons #pandas got some internal refactorings (by @TomAugspurger) so you can define your own data types
#:linguaggi di programmazione
::: jankatins

Why should I care about Kubernetes, Docker, and Container Orchestration?
#:Web, Internet
::: Donearm

shame on you @LALIGNEDEFREE for this
#:open source
::: zacchiro

‘Fiction is outperforming reality’: how YouTube’s algorithm distorts truth
#:caos informativo, fake news, bufale
::: marcelsalathe

An Exhaustive Guide to Writing Dockerfiles for Node.js Web Apps
#:manuali, how to
::: newsycombinator

3 command-line tools for feigning productivity
#:tools, componenti software
::: lucaciavatta

How to start writing macros in LibreOffice Basic
#:linguaggi di programmazione
::: lucaciavatta

Bella infografica sulle infografiche standard utilizzabili dai media
#:media
::: cmnit

La Folha, the largest Brazilian newspaper, will stop publishing content on Facebook. It has 6M followers
#:social media
::: filloux ::: micheleboldrin

Google Executives Are Floating a Plan To Fight Fake News on Facebook and Twitter
#:caos informativo, fake news, bufale #:social media
::: Slashdot

Intel Replaces its Buggy Fix for Skylake PCs
#:bug #:hardware
::: Slashdot

I’m impressed – although this is a small sample of users, less than a quarter of respondents exclusively use #Python 2
#:linguaggi di programmazione
::: astrofrog

Salaries For Workers in Technology Roles, Including Software Engineers and Product Managers, Peak Around Age 45
#:economia
::: Slashdot

In other words: It’s bad!
#:copyright e brevetti
::: FixIt_EU

Piuttosto che niente è meglio piuttosto
#:media
::: manteblog ::: mante

Racket’s “lazy” module does this and mentions monads specifically
#:programmazione funzionale
::: TheMichaelBurge

There’s a guy in Switzerland who has edited over 100,000 Stack Overflow posts
#:social media
::: lizardbill

A hacker proved a security flaw exists in the Vatican’s news website by having it declare ‘God is an onion’
Inti rockz! 💥
#:sicurezza, spionaggio, virus
::: businessinsider

Why #Linux is better than #Windows or #macOS for security
#:sicurezza, spionaggio, virus
::: sdallagata

Finally someone used the blink ansi code that I added for @replit
#:linguaggi di programmazione #:Web, Internet
::: amasad

My new book is out! It is called “Exploring ReasonML and functional programming”
#:programmazione funzionale
::: reasonmlhub

Clojurists Together is excited to announce the projects in our first funding round
#:linguaggi di programmazione
::: cljtogether

New artificially intelligent software can detect phony stories, nudity, malware, and a host of other types of problematic content
#:caos informativo, fake news, bufale
::: techreview

Vi spiego perché cyber security e rivoluzione digitale sono le vere sfide della classe politica. Parla @RosaCalipari (Copasir)
#:sicurezza, spionaggio, virus
::: formichenews

Learning Go as a Node.js Developer
#:linguaggi di programmazione
::: Donearm

nspect and manage processes with ps
#:tools, componenti software
::: lucaciavatta

How to use Twine and SugarCube to create interactive adventure games
#:tools, componenti software
::: lucaciavatta

Il fatto che non riesca a sapere chi ha accesso ai miei dati non è un elemento di libertà
#:sicurezza, spionaggio, virus
::: azuech

Collabora Online 3.0 is out! Try the new release and enjoy the new dialogs for Writer, Calc and Impress – and more
#:open source
::: CollaboraOffice

c’è una legge in Italia che sanziona le intrusioni informatiche ma tutto è sempre più complesso di come appare
#:sicurezza, spionaggio, virus
::: ORARiccardo

Understanding the C/C++ memory model
#:programming, codice, snippet
::: b3h3m0th

5 Awesome Features in VLC 3.0
#:tools, componenti software
::: omgubuntu

Il ritorno di Linspire, con una veloce recensione a cura dell’esperto
#:sistemi operativi
::: Dario Cavedon

Ubuntu 18.04 LTS Could Come with Snap Apps Preinstalled
#:sistemi operativi
::: Slashdot

Have you HTTPS’d all your things yet? No? Then you’re not gonna be real happy if you haven’t done it by July
#:Web, Internet #:sicurezza, spionaggio, virus
::: troyhunt

This week was so incredible, I had to blog about it
#:linguaggi di programmazione
::: aaron_turon

Wrote in @esquire about why we should break up big tech
#:economia #:ditte
::: profgalloway

ALGOL 68 fans know its statement brackets are like if-fi, do-od; Unix geeks know that Stephen Bourne of shell fame was also an ALGOL 68 fan
#:storia
::: fanf

Major Websites Are Planning a ‘Day of Action’ To Block Repeal of Net Neutrality
#:Web, Internet
::: Slashdot

cerca i 16 cerchi

Science and Technology links (February 9th, 2018)
#:Web, Internet
::: lemire

Android Messages May Soon Let You Text From the Web
#:dispositivi mobili #:Web, Internet
::: Slashdot

My new article in the @washingtonpost on the how the world opened its eyes to a new cyber power. A story about signaling
#:sicurezza, spionaggio, virus
::: smeetsmwe

Unix Architecture Evolution from the 1970 PDP-7 to the 2018 FreeBSD
#:storia
::: b3h3m0th

Launch Single-File Source-Code Programs
#:linguaggi di programmazione
::: Devoxx

La bellissima storia di Wikileaks Italian e il M5S
#:caos informativo, fake news, bufale
::: DavidPuente

Top JavaScript Libraries & Tech to Learn in 2018
#:linguaggi di programmazione
::: YanJeanLee

KPTI/KAISER Meltdown Initial Performance Regressions
#:hardware #:bug
::: b3h3m0th

An Opinionated Guide to Haskell in 2018
se supero il livello n00b con Haskell ci tornerò; Lexi Lambda rockz! 💥
#:programmazione funzionale
::: lexi_lambda

“Overload Journal” issue 143
#:programming, codice, snippet
::: b3h3m0th

Haskell – 120 – altre monadi ancora – 1

Continuo da qui, copio qui.

We’ve seen how monads can be used to take values with contexts and apply them to functions and how using >>= or do notation allows us to focus on the values themselves while the context gets handled for us.

We’ve met the Maybe monad and seen how it adds a context of possible failure to values. We’ve learned about the list monad and saw how it lets us easily introduce non-determinism into our programs. We’ve also learned how to work in the IO monad, even before we knew what a monad was!

Now we’re going to learn about a few other monads. We’ll see how they can make our programs clearer by letting us treat all sorts of values as monadic ones. Exploring a few monads more will also solidify our intuition for monads.

The monads that we’ll be exploring are all part of the mtl package. A Haskell package is a collection of modules. The mtl package comes with the Haskell Platform, so you probably already have it. To check if you do, type ghc-pkg list in the command-line. This will show which Haskell packages you have installed and one of them should be mtl, followed by a version number.

* hs-120 $ ghc-pkg list
/usr/lib/ghc/package.conf.d
    Cabal-1.24.2.0
    array-0.5.1.1
    base-4.9.1.0
    binary-0.8.3.0
    bytestring-0.10.8.1
    containers-0.5.7.1
    deepseq-1.4.2.0
    directory-1.3.0.0
    filepath-1.4.1.1
    ghc-8.0.2
    ghc-boot-8.0.2
    ghc-boot-th-8.0.2
    ghc-prim-0.5.0.0
    ghci-8.0.2
    haskeline-0.7.3.0
    hoopl-3.10.2.1
    hpc-0.6.0.3
    integer-gmp-1.0.0.1
    pretty-1.1.3.3
    process-1.4.3.0
    rts-1.0
    template-haskell-2.11.1.0
    terminfo-0.4.0.2
    time-1.6.0.1
    transformers-0.5.2.0
    unix-2.7.2.1
    xhtml-3000.2.1

Panico 😐 manca 😡

Provo a installarlo, seguendo le dritte qui e qui.

* hs-120 $ cabal update
Il programma "cabal" non è attualmente installato. È possibile installarlo digitando:
sudo apt install cabal-install
* hs-120 $ sudo apt install cabal-install

e parte l’installazione ma poi

* hs-120 $ cabal install mtl
Config file path source is default config file.
Config file /home/juhan/.cabal/config not found.
Writing default configuration to /home/juhan/.cabal/config
Warning: The package list for 'hackage.haskell.org' does not exist. Run 'cabal
update' to download it.
cabal: There is no package named 'mtl'.
You may need to run 'cabal update' to get the latest list of available
packages.

Allora…

* hs-120 $ cabal update
Downloading the latest package list from hackage.haskell.org
* hs-120 $

e…

* hs-120 $ ghc-pkg list | grep mtl
* hs-120 $

niente da fare!

Ma riprovo:

* hs-120 $ cabal update
Downloading the latest package list from hackage.haskell.org
Skipping download: local and remote files match.
* hs-120 $ cabal install mtl
Resolving dependencies...
Downloading mtl-2.2.1...
Configuring mtl-2.2.1...
Building mtl-2.2.1...
Installed mtl-2.2.1
* hs-120 $

e adesso

* hs-120 $ ghc-pkg list | grep mtl
    mtl-2.2.1
* hs-120 $

OK, è stata dura 😐 pausa 😯

🤣

Haskell – 119 – un po’ di monadi – 7

Continuo da qui, copio qui.

Leggi delle monadi
Just like applicative functors, and functors before them, monads come with a few laws that all monad instances must abide by. Just because something is made an instance of the Monad type class doesn’t mean that it’s a monad, it just means that it was made an instance of a type class. For a type to truly be a monad, the monad laws must hold for that type. These laws allow us to make reasonable assumptions about the type and its behavior.

Haskell allows any type to be an instance of any type class as long as the types check out. It can’t check if the monad laws hold for a type though, so if we’re making a new instance of the Monad type class, we have to be reasonably sure that all is well with the monad laws for that type. We can rely on the types that come with the standard library to satisfy the laws, but later when we go about making our own monads, we’re going to have to manually check the if the laws hold. But don’t worry, they’re not complicated.

Left identity
The first monad law states that if we take a value, put it in a default context with return and then feed it to a function by using >>=, it’s the same as just taking the value and applying the function to it. To put it formally:

return x >>= f is the same damn thing as f x.

If you look at monadic values as values with a context and return as taking a value and putting it in a default minimal context that still presents that value as its result, it makes sense, because if that context is really minimal, feeding this monadic value to a function shouldn’t be much different than just applying the function to the normal value, and indeed it isn’t different at all.

For the Maybe monad return is defined as Just. The Maybe monad is all about possible failure, and if we have a value and want to put it in such a context, it makes sense that we treat it as a successful computation because, well, we know what the value is. Here’s some return usage with Maybe:

Prelude> return 3 >>= (\x -> Just (x+100000))
Just 100003
Prelude> (\x -> Just (x+100000)) 3
Just 100003

For the list monad return puts something in a singleton list. The >>= implementation for lists goes over all the values in the list and applies the function to them, but since there’s only one value in a singleton list, it’s the same as applying the function to that value:

Prelude> return "WoM" >>= (\x -> [x,x,x])
["WoM","WoM","WoM"]
Prelude> (\x -> [x,x,x]) "WoM"
["WoM","WoM","WoM"]

We said that for IO, using return makes an I/O action that has no side-effects but just presents a value as its result. So it makes sense that this law holds for IO as well.

Right identity
The second law states that if we have a monadic value and we use >>= to feed it to return, the result is our original monadic value. Formally:

m >>= return is no different than just m.

This one might be a bit less obvious than the first one, but let’s take a look at why it should hold. When we feed monadic values to functions by using >>=, those functions take normal values and return monadic ones. return is also one such function, if you consider its type. Like we said, return puts a value in a minimal context that still presents that value as its result. This means that, for instance, for Maybe, it doesn’t introduce any failure and for lists, it doesn’t introduce any extra non-determinism. Here’s a test run for a few monads:

Prelude> Just "move on up" >>= (\x -> return x)
Just "move on up"
Prelude> [1,2,3,4] >>= (\x -> return x)
[1,2,3,4]
Prelude> putStrLn "Wah!" >>= (\x -> return x)
Wah!

If we take a closer look at the list example, the implementation for >>= is:

xs >>= f = concat (map f xs)

So when we feed [1,2,3,4] to return, first ççreturn gets mapped over [1,2,3,4], resulting in [[1],[2],[3],[4]] and then this gets concatenated and we have our original list.

Left identity and right identity are basically laws that describe how return should behave. It’s an important function for making normal values into monadic ones and it wouldn’t be good if the monadic value that it produced did a lot of other stuff.

Associativity
The final monad law says that when we have a chain of monadic function applications with >>=, it shouldn’t matter how they’re nested. Formally written:

Doing (m >>= f) >>= g is just like doing m >>= (\x -> f x >>= g).

Hmmm, now what’s going on here? We have one monadic value, m and two monadic functions f and g. When we’re doing (m >>= f) >>= g, we’re feeding m to f, which results in a monadic value. Then, we feed that monadic value to g. In the expression m >>= (\x -> f x >>= g), we take a monadic value and we feed it to a function that feeds the result of f x to g. It’s not easy to see how those two are equal, so let’s take a look at an example that makes this equality a bit clearer.

Remember when we had our tightrope walker Pierre walk a rope while birds landed on his balancing pole? To simulate birds landing on his balancing pole, we made a chain of several functions that might produce failure:

Devo recuperare le definizioni di landLeft e lantRight contenute nel file pole-r.hs di questo post.

*Main> :l pole-r
[1 of 1] Compiling Main             ( pole-r.hs, interpreted )
Ok, modules loaded: Main.
*Main> return (0,0) >>= landRight 2 >>= landLeft 2 >>= landRight 2
Just (2,4)

We started with Just (0,0) and then bound that value to the next monadic function, landRight 2. The result of that was another monadic value which got bound into the next monadic function, and so on. If we were to explicitly parenthesize this, we’d write:

*Main> ((return (0,0) >>= landRight 2) >>= landLeft 2) >>= landRight 2
Just (2,4)

But we can also write the routine like this:

return (0,0) >>= (\x ->
landRight 2 x >>= (\y ->
landLeft 2 y >>= (\z ->
landRight 2 z)))

Nota: devo scriverlo su un’unica riga, ovviamente.

*Main> return (0,0) >>= (\x -> landRight 2 x >>= (\y -> landLeft 2 y >>= (\z -> landRight 2 z)))
Just (2,4)

return (0,0) is the same as Just (0,0) and when we feed it to the lambda, the x becomes (0,0). landRight takes a number of birds and a pole (a tuple of numbers) and that’s what it gets passed. This results in a Just (0,2) and when we feed this to the next lambda, y is (0,2). This goes on until the final bird landing produces a Just (2,4), which is indeed the result of the whole expression.

So it doesn’t matter how you nest feeding values to monadic functions, what matters is their meaning. Here’s another way to look at this law: consider composing two functions, f and g. Composing two functions is implemented like so:

(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = (\x -> f (g x))

If the type of g is a -> b and the type of f is b -> c, we arrange them into a new function which has a type of a -> c, so that its parameter is passed between those functions. Now what if those two functions were monadic, that is, what if the values they returned were monadic values? If we had a function of type a -> m b, we couldn’t just pass its result to a function of type b -> m c, because that function accepts a normal b, not a monadic one. We could however, use >>= to make that happen. So by using >>=, we can compose two monadic functions:

comp.hs

(<= (b -> m c) -> (a -> m b) -> (a -> m c)
f <= g x >>= f)

So now we can compose two monadic functions:

*Main> :l comp
[1 of 1] Compiling Main             ( comp.hs, interpreted )
Ok, modules loaded: Main.
*Main> let f x = [x,-x]
*Main> let g x = [x*3,x*2]
*Main> let h = f <= h 3
[9,-9,6,-6]

Cool. So what does that have to do with the associativity law? Well, when we look at the law as a law of compositions, it states that f <=< (g <=< h) should be the same as (f <=< g) <=< h. This is just another way of saying that for monads, the nesting of operations shouldn’t matter.

If we translate the first two laws to use <=<, then the left identity law states that for every monadic function f, f <=&lt; return is the same as writing just f and the right identity law says that return <=< f is also no different from f.

This is very similar to how if f is a normal function, (f . g) . h is the same as f . (g . h), f . id is always the same as f and id . f is also just f.

In this chapter, we took a look at the basics of monads and learned how the Maybe monad and the list monad work. In the next chapter, we’ll take a look at a whole bunch of other cool monads and we’ll also learn how to make our own.

Panico? 😐 kwasy 😋

😎

AI, innovazioni e blockchain – 8

Il Blockchain sta monopolizzando la rassegna, anche perché il Bitcoin è ballerino da non credere; sarà una cosa seria? 😐

MIT algorithm predicts price of Bitcoin, doubles investment in 2 months
#:blockchain e crypto*
::: MIT_CSAIL

Why the Future is Parallel
#:innovazioni, futuro
::: ElixirTip

Massive #Cryptocurrency Mining Botnet Malware—Smominru—Silently Made $3.6 Million in #Monero by Infecting Over 526,000 PCs Worldwide Using Leaked #NSA Exploit
#:blockchain e crypto*
::: TheHackersNews

#Blockchain has the potential to be truly transformative for financial services and markets, but not only
#:blockchain e crypto*
::: VDombrovskis

5 Areas Where #IoT is Having the Most Business Impact
#:Internet of things
::: HitachiVantara

How DIY Rebels Are Working To Replace Tech Giants
#:economia
::: Slashdot

if this is Feb 1, April 1 is going to be hardcore
How $800k Evaporated from the PoWH Coin Ponzi Scheme Overnight
#:blockchain e crypto*
::: johnregehr ::: glipari

Bitcoin hits a 2018 low as concerns mount on regulation and viability
#:blockchain e crypto*
::: business ::: CharlieShrem

“Nobody can control bitcoin” …
#:blockchain e crypto*
::: glipari

Jason Weingart

How else a Ponzi scheme is expected to end?
#:blockchain e crypto*
::: glipari

How Amazon Rebuilt Itself Around Artificial Intelligence
#:artificial intelligence
::: marcelsalathe

ARM Exploitation for IoT
#:Internet of things
::: b3h3m0th

Great program to diversify AI by lowering barriers into AI study for underrepresented students in grades 9–12
#:artificial intelligence #:scuola, educazione
::: lewisshepherd

Fra qualche anno (praticamente domani) i contenuti rappresenteranno uno dei punti di forza dell’economia digitale
#:dati, raccolta
::: SergioGridelli

L’illusione di Bitcoin, una moneta troppo virtuale per poter (r)esistere
#:blockchain e crypto*
::: Scacciavillani

India Rejects Cryptocurrency, But It Isn’t Giving Up On Blockchain
#:blockchain e crypto*
::: Slashdot

The #EuropeanCommission aims to develop a common approach on #Blockchain technology for the #EU in the international arena
#:blockchain e crypto*
::: PaoloBarucca

Uber Study Says Self-Driving Trucks Will Result In More Truck Drivers, Not Less
#:innovazioni, futuro
::: Slashdot

Elon Musk Sells $10 Million in Flamethrowers in Four Days
chissà se la dogana avrebbe qualcosa a ridire? perché io ne sono attualmente sprovvisto 😡
#:innovazioni, futuro
::: Slashdot

Five Major Credit Cards Are Now Blocking Cryptocurrency Purchases
#:blockchain e crypto*
::: Slashdot

Finland Will Introduce a Mobile ‘Driver’s License’ App
#:innovazioni, futuro
::: Slashdot

The tech underlying Bitcoin and blockchain in general maybe interesting with some real uses, but this is a classic speculative asset bubble
#:blockchain e crypto*
::: zeynep

The crypto asset learning curve is steep, but you need not pay anyone to teach you – the only investment required is time
#:blockchain e crypto*
::: lopp

Ma se le cryptocurrencies sono “beni rifugio”, perche’ crollano del 15-50% quando lo stock market cala del 5%?
#:blockchain e crypto*
::: micheleboldrin

US Regulators To Back More Oversight of Virtual Currencies
#:blockchain e crypto*
::: Slashdot

In 30 years we’ll look back and say Geoffrey Hinton is the Einstein of deep learning & this thing we’re calling AI
#:artificial intelligence
::: RichRogersIoT

Last year, it seemed that nothing could stop the virtual currency boom
#:blockchain e crypto*
::: nytimestech

Man Sues T-Mobile For Allegedly Failing To Stop Hackers From Stealing His Cryptocurrency
#:blockchain e crypto*
::: Slashdot

Is it too soon to rename
#:blockchain e crypto*
::: perrymetzger

Questo simpatico #robot-orsetto potrebbe sostituire l’80% del personale di cura degli anziani in Giappone entro 3 anni
#:innovazioni, futuro
::: Aspeniaonline

US Startups Don’t Want To Go Public Anymore
#:innovazioni, futuro
::: Slashdot

Quale ruolo per le #biblioteche nell’età digitale?
#:innovazioni, futuro
::: demartin

Glad and grateful to join the @bitcoinprivate team as an ambassador. Spread the love ❤
#:blockchain e crypto*
::: Alexintosh

Just because we can find a place for #bitcoin on the “money flower” does not mean that it constitutes good money
#:blockchain e crypto*
::: BIS_org

We spent the last 70 years connecting & empowering humans. We’ll spend the next 70 connecting & empowering machines
#:innovazioni, futuro
::: RichRogersIoT

Mai fregato nulla di colonizzare Marte ma la quantita’ cumulata d’intelligenza umana che sottende azioni come queste e’ semplicemente entusiasmante
#.inno #:prot
::: micheleboldrin

How to learn Deep Learning in 6 months
#:deep learning
::: Donearm

4 Cryptocurrency Trends to Watch in 2018
#:blockchain e crypto*
::: Hacker Noon

Brand new technology in the classroom
#:innovazioni, futuro
::: ETH_en

Get Ready For Most Cryptocurrencies to Hit Zero, Goldman Says
#:blockchain e crypto*
::: Slashdot

Great interview with MIT’s Autor on the role of tech on inequality (via @emily_erikson). This resonates strongly with us at @epfl_exts. “Highly educated” shouldn’t only depend on what you did up to age 23…
#:innovazioni, futuro #:scuola, educazione
::: marcelsalathe ::: marcelsalathe

Chinese Companies Hunt for AI Talent at American Conference
#:artificial intelligence
::: Slashdot

Dark Secrets of AI – No one really knows how the most advanced algorithms do what they do. That could be a problem
#:artificial intelligence
::: RichRogersIoT

Foxconn Unit To Cut Over 10,000 Jobs As Robotics Take Over
#:innovazioni, futuro #:economia
::: Slashdot

Each bubble has been ~10 times as large as the last. If it happens three more times, Bitcoin will represent most of the (notional) wealth in the world
#:blockchain e crypto*
::: Noahpinion

European Banks Could Soon Hold Bitcoin, Admits ECB President
#:blockchain e crypto*
::: Crypt0_God

Small cities face greater impact from automation
#:innovazioni, futuro
::: alexvespi

Police In China Are Scanning Travelers With Facial Recognition Glasses
#:artificial intelligence
::: Slashdot

IL MANIFESTO DI #BLOCKCHAINEDU 🇮🇹 “#Bitcoin e #Blockchain come opportunità di crescita per l’italia”
#:blockchain e crypto*
::: BlockchainEduIT

Bitcoin Private: By The People, For The People
#:blockchain e crypto*
::: Alexintosh

Attackers Drain CPU Power From Water Utility Plant In Cryptojacking Attack
#:blockchain e crypto*
::: Slashdot

Ancora sulle traduzioni automatiche

Continuo le mie prove con i traduttori automatici, con l’aiuto di una giovane amica che ha trovato il post precedente utile e divertente.

Perché non cominciare proprio dal primo esempio di Douglas Hofstadter, ci riserverà delle sorprese; questo è il testo originale:

In their house, everything comes in pairs. There’s his car and her car, his towels and her towels, and his library and hers.

La risposta di DeepL:

Nella loro casa, tutto è in coppia. C’è la sua auto e la sua auto, i suoi asciugamani e asciugamani, la sua biblioteca e la sua.

Quella di Bing:

Nella loro casa, tutto viene a coppie. C’è la sua macchina, la sua macchina, i suoi asciugamani, i suoi asciugamani, la sua biblioteca e la sua.

E quella di Google:

Nella loro casa, tutto viene a coppie. C’è la sua macchina e la sua macchina, i suoi asciugamani e gli asciugamani, e la sua biblioteca e la sua.

Tutte molto simili. E sbagliate, tutte allo stesso modo. Il problema è quello dei pronomi possessivi, come indicato da Doug. Inoltre DeepL lascia uno spazio dopo l’apostrofo in “C’è”. Peccato non conoscere qualche altra lingua, per esempio il tedesco, dove entrerebbero in gioco altri elementi ancora.

Girolando su Twitter abbiamo raccolto (ahimè, senza salvare il link) qualche esempio che riporto quasi senza commenti.

In #Portugal ist geschehen, was man sich in Deutschland kaum vorstellen kann: Die Sozialdemokratie verweigerte sich einer #GroKo, bildete eine #Minderheitsregierung. Arbeitsfreie Feiertage und die 35-Stunden-Woche im Öfftl. Dienst wurden wieder eingeführt.

DeepL

In #Portogallo è successo quello che difficilmente si può immaginare in Germania: La socialdemocrazia si rifiutò a un #GroKo, formando un governo di #minorità. Sono state reintrodotte le ferie senza lavoro e la settimana di 35 ore nel servizio pubblico.

Bing

In #Portugal che cosa può appena essere immaginato in Germania: la democrazia sociale rifiutata una #GroKo, formata una zeitschrift-luxemburg.de/35-stunden-woche-als-erster-schritt/ …. Vacanze non lavorative e la settimana di 35 ore nel ÖFFTL. Servizio sono stati reintrodotti.

Google

In #Portugal è successo quello che difficilmente si può immaginare in Germania: i socialdemocratici hanno rifiutato un #GroKo, formato un #Minderschaftsregierung. Vacanze non lavorative e la settimana di 35 ore all’aperto. Il servizio è stato reintrodotto.

Qui meglio Google; a DeepL (è tedesco) manca qualche parola; Bing si perde.

Ein Faschist schießt im italienischen #Macerata aus einem fahrenden Auto, verletzt mehrere Migranten, einen davon lebensgefährlich. Vor der Festnahme zeigt er den Hitlergruß. In Deutschland ist dieser mutmaßliche Terroranschlag weder eine Eilmeldung noch ein Twitter-Trend.

DeepL

Un fascista spara fuori da una macchina da guida in Italia #Macerata, ferisce diversi migranti, uno dei quali mortale. Prima dell’arresto, saluta a Hitler. In Germania, questo presunto attentato terroristico non è né un lampo di notizie né una tendenza a twitterare.

Bing

Un fascista spara in italiano #Macerata da una macchina di guida, ferendo diversi migranti, uno di loro pericolo di vita. Prima dell’arresto egli mostra il saluto di Hitler. In Germania, questo presunto attacco terroristico non è né una novità né una tendenza Twitter.

Google

Un fascista spara in italiano #Macerata da un’auto in movimento, ferendo diversi migranti, uno dei quali pericoloso. Prima dell’arresto, mostra il saluto di Hitler. In Germania, questo presunto attacco terroristico non è né una novità né una tendenza di Twitter.

Anche qui errori simili “im italienischen” viene frainteso; il saluto è nel tweet, come pure la chiusura. Risultati comprensibili ma da interpretare.

OH:
– Bartender: What’s your name?
– @arnaudbenard: Arnaud
– Bartender: You don’t know your name?
– @arnaudbenard : Arnaud, not “I don’t know”
#TravelingWhileFrench

DeepL

OH:
Bartender: Qual è il tuo nome?
@arnaudbenard: Arnaudard
Bartender: Non conosci il tuo nome?
Arnaudbenard: Arnaud, non “Non lo so”.
ViaggioIl Francese

Bing

Oh:
– barista: qual è il tuo nome?
– @arnaudbenard: Arnaud
– barista: non sai il tuo nome?
– @arnaudbenard: Arnaud, non “non lo so”
#TravelingWhileFrench

Google

OH:
– Barista: come ti chiami?
– @arnaudbenard: Arnaud
– Barista: non conosci il tuo nome?
– @arnaudbenard: Arnaud, non “Non lo so”
#TravelingWhileFrench

Qui la storiella franco-inglese. A DeepL mancano la parola “barista” e non capisce il nome. Nota perso: questo cognome è presente anche qui da noi in (almeno) due versioni (tradotte), Arnò e Arnaudo.

Wir haben in der Flüchtlingspolitik jedes Maß verloren 😡

DeepL

Abbiamo perso ogni misura nella politica per i rifugiati1?

Bing

Abbiamo perso ogni misura nella politica dei rifugiati

Google

Abbiamo perso ogni misura nella politica dei rifugiati 😡

Stessa risposta (quasi) per i tre traduttori. DeepL traduce l’emoji in “1l?”.

Ein 12jähriger Junge wurde aus #Hessen alleine nach #Mazedonien abgeschoben – obwohl seine Großmutter in Deutschland lebt und das alleinige Sorgerecht innehat. Der hessische Flüchtlingsrat berichtet über den Fall

DeepL

Un ragazzo di 12 anni è stato deportato da #Hesse a #Macedonia solo – anche se sua nonna vive in Germania e ha la custodia esclusiva. Il Consiglio per i rifugiati dell’Assia riferisce sul caso

Bing

Un ragazzo 12jähriger è stato espulso da #Hessen da solo a #Mazedonien-anche se sua nonna vive in Germania e mantiene la custodia esclusiva. I rapporti del rifugiato della tela di iuta sul caso

Google

Un ragazzo di 12 anni è stato deportato da #Hessen a #Macedonia da solo – sebbene sua nonna viva in Germania e abbia la custodia esclusiva. Il Consiglio dei profughi dell’Assia riferisce sul caso

Qui Bing si perde almeno due volte. Per tutti traduzione troppo letterale di “alleinige Sorgerecht”.

银霞~你那好冷的小手

DeepL
non traduce, conosce solo:
Italiano
Inglese
Tedesco
Francese
Spagnolo
Olandese
Polacco

Bing

Bancha ~ la tua piccola mano fredda.

Google

Yinxia ~ la tua mano è così fredda

Qui ci vorrebbe un ninjia esperto in manga/anime. Probabilmente meglio Google. 我不懂中文和日文 | 私は中国語と日本語を知らない

2018 #평창동계올림픽 대회⭐
벅찬 감동과 짜릿함을 안겨줄
#올림픽선수 들의 #아름다운도전 이야기,
차근차근 들어보실래요?

Bing

2018 #평창동계올림픽 torneo ⭐
Impressionante è
#아름다운도전 storie di #올림픽선수,
Vuoi entrare?

Google

2018 # Pyeongchang Giochi olimpici invernali
Entusiasmo ed eccitazione
# Belle storie di sfide degli atleti olimpici,
Ti piacerebbe sentirlo?

Anche qui molto meglio Google, anche se tenete conto che 나는 한국어를 모른다.

Per finire un paio di frasi di un racconto (eccezionale):

They say that the fifth elephant came screaming and trumpeting through the atmosphere of the young world all those years ago and landed hard enough to split continents and raise mountains.
No one actually saw it land, which raised the interesting philosophical question: when millions of tons of angry elephant come spinning through the sky, and there is no one to hear it, does it — philosophically speaking — make a noise?

DeepL

Dicono che il quinto elefante è venuto urlando e trombando attraverso l’atmosfera del mondo giovane tutti quegli anni fa e atterrato abbastanza duro per dividere i continenti e innalzare le montagne.
In realtà nessuno l’ha vista atterrare, il che ha sollevato l’interessante questione filosofica: quando milioni di tonnellate di elefante arrabbiato vengono in giro per il cielo, e non c’è nessuno a sentirlo, fa forse – filosoficamente parlando – un rumore?

Bing

Dicono che il quinto elefante è venuto urlando e trombando attraverso l’atmosfera del mondo giovane tutti quegli anni fa ed è atterrato abbastanza duro per dividere continenti e sollevare le montagne.
Nessuno in realtà ha visto la terra, che ha sollevato l’interessante questione filosofica: quando milioni di tonnellate di elefante arrabbiato venire filatura attraverso il cielo, e non c’è nessuno a sentirlo, lo fa-filosoficamente parlando-fare un rumore?

Google

Dicono che il quinto elefante è venuto a urlare e barrito attraverso l’atmosfera del giovane mondo tutti quegli anni fa e ha atterrato abbastanza forte da dividere i continenti e sollevare montagne.
Nessuno in realtà l’ha visto atterrare, il che ha sollevato l’interessante questione filosofica: quando milioni di tonnellate di elefanti arrabbiati vengono a ruotare nel cielo, e non c’è nessuno che lo ascolti, lo fa – filosoficamente parlando – fa rumore?

Non ci siamo: OK, si capisce il senso ma non si dice così. Poi Il quinto elefante di Terry Pratchett lo trovate anche in italiano. Ed è un racconto bello e istruttivo; altamente raccomandato.

Aggiornamento
Problema numerico per i norvegesi, qui.
Difficoltà di traduzione per le insegnanti, in italiano la parola non cambia con il genere, in tedesco e francese (e probabilmente non solo) i traduttori auomatici hanno problemi. Ho pasato un oretta della domenica pomeriggio trovando cose ma non posto il post (ahemmm…) preparato. Si parte da qui.

😋

Haskell – 118 – un po’ di monadi – 6

Continuo da qui, copio qui, scrollare fino a “A knight’s quest”.

Il cavallo ce la può fare?
Here’s a problem that really lends itself to being solved with non-determinism. Say you have a chess board and only one knight piece on it. We want to find out if the knight can reach a certain position in three moves. We’ll just use a pair of numbers to represent the knight’s position on the chess board. The first number will determine the column he’s in and the second number will determine the row.

Let’s make a type synonym for the knight’s current position on the chess board:

type KnightPos = (Int,Int)

So let’s say that the knight starts at (6,2). Can he get to (6,1) in exactly three moves? Let’s see. If we start off at (6,2) what’s the best move to make next? I know, how about all of them! We have non-determinism at our disposal, so instead of picking one move, let’s just pick all of them at once. Here’s a function that takes the knight’s position and returns all of its next moves:

moveKnight :: KnightPos -> [KnightPos]
moveKnight (c,r) = do
  (c',r') <- [(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1)
             ,(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2)
             ]
  guard (c' `elem` [1..8] && r' `elem` [1..8])
  return (c',r')

The knight can always take one step horizontally or vertically and two steps horizontally or vertically but its movement has to be both horizontal and vertical. (c',r') takes on every value from the list of movements and then guard makes sure that the new move, (c',r') is still on the board. If it it’s not, it produces an empty list, which causes a failure and return (c',r') isn’t carried out for that position.

This function can also be written without the use of lists as a monad, but we did it here just for kicks. Here is the same function done with filter:

moveKnight :: KnightPos -> [KnightPos]
moveKnight (c,r) = filter onBoard
  [(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1)
  ,(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2)
  ]
  where onBoard (c,r) = c `elem` [1..8] && r `elem` [1..8]

Ahemmm… devo caricare guard, file kn.hs.

kn.hs

class Monad m => MonadPlus m where
  mzero :: m a
  mplus :: m a -> m a -> m a

instance MonadPlus [] where
  mzero = []
  mplus = (++)

guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero

type KnightPos = (Int,Int)

moveKnight :: KnightPos -> [KnightPos]
moveKnight (c,r) = do
  (c',r') <- [(c+2,r-1),(c+2,r+1),(c-2,r-1),(c-2,r+1)
             ,(c+1,r-2),(c+1,r+2),(c-1,r-2),(c-1,r+2)
             ]
  guard (c' `elem` [1..8] && r' `elem` [1..8])
  return (c',r')

Both of these do the same thing, so pick one that you think looks nicer. Let’s give it a whirl:

Prelude> :l kn
[1 of 1] Compiling Main             ( kn.hs, interpreted )
Ok, modules loaded: Main.
*Main> moveKnight (6,2)
[(8,1),(8,3),(4,1),(4,3),(7,4),(5,4)]
*Main> moveKnight (8,1)
[(6,2),(7,3)]

Works like a charm! We take one position and we just carry out all the possible moves at once, so to speak. So now that we have a non-deterministic next position, we just use >>= to feed it to moveKnight. Here’s a function that takes a position and returns all the positions that you can reach from it in three moves:

in3 :: KnightPos -> [KnightPos]
in3 start = do
  first <- moveKnight start
  second <- moveKnight first
  moveKnight second

If you pass it (6,2), the resulting list is quite big, because if there are several ways to reach some position in three moves, it crops up in the list several times. The above without do notation:

in3 start = return start >>= moveKnight >>= moveKnight >>= moveKnight

Using >>= once gives us all possible moves from the start and then when we use >>= the second time, for every possible first move, every possible next move is computed, and the same goes for the last move.

Putting a value in a default context by applying return to it and then feeding it to a function with >>= is the same as just normally applying the function to that value, but we did it here anyway for style.

Now, let’s make a function that takes two positions and tells us if you can get from one to the other in exactly three steps:

canReachIn3 :: KnightPos -> KnightPos -> Bool
canReachIn3 start end = end `elem` in3 start

We generate all the possible positions in three steps and then we see if the position we’re looking for is among them. So let’s see if we can get from (6,2) to (6,1) in three moves:

OK, aggiungo questo codice a kn.hs ottenendo kn3.hs.

*Main> :l kn3
[1 of 1] Compiling Main             ( kn3.hs, interpreted )
Ok, modules loaded: Main.
*Main> (6,2) `canReachIn3` (6,1)
True

Yes! How about from (6,2) to (7,3)?

*Main> (6,2) `canReachIn3` (7,3)
False

No! As an exercise, you can change this function so that when you can reach one position from the other, it tells you which moves to take. Later on, we’ll see how to modify this function so that we also pass it the number of moves to take instead of that number being hardcoded like it is now.

😐

Haskell – 117 – un po’ di monadi – 5

Continuo da qui, copio qui.

Liste e monadi
So far, we’ve seen how Maybe values can be viewed as values with a failure context and how we can incorporate failure handling into our code by using >>= to feed them to functions. In this section, we’re going to take a look at how to use the monadic aspects of lists to bring non-determinism into our code in a clear and readable manner.

We’ve already talked about how lists represent non-deterministic values when they’re used as applicatives. A value like 5 is deterministic. It has only one result and we know exactly what it is. On the other hand, a value like [3,8,9] contains several results, so we can view it as one value that is actually many values at the same time. Using lists as applicative functors showcases this non-determinism nicely:

Prelude> (*)  [1,2,3]  [10,100,1000]
[10,100,1000,20,200,2000,30,300,3000]

All the possible combinations of multiplying elements from the left list with elements from the right list are included in the resulting list. When dealing with non-determinism, there are many choices that we can make, so we just try all of them, and so the result is a non-deterministic value as well, only it has many more results.

This context of non-determinism translates to monads very nicely. Let’s go ahead and see what the Monad instance for lists looks like:

instance Monad [] where
  return x = [x]
  xs >>= f = concat (map f xs)
  fail _ = []

return does the same thing as pure, so we should already be familiar with return for lists. It takes a value and puts it in a minimal default context that still yields that value. In other words, it makes a list that has only that one value as its result. This is useful for when we want to just wrap a normal value into a list so that it can interact with non-deterministic values.

To understand how >>= works for lists, it’s best if we take a look at it in action to gain some intuition first. >>= is about taking a value with a context (a monadic value) and feeding it to a function that takes a normal value and returns one that has context. If that function just produced a normal value instead of one with a context, >>= wouldn’t be so useful because after one use, the context would be lost. Anyway, let’s try feeding a non-deterministic value to a function:

Prelude> [3,4,5] >>= \x -> [x,-x]
[3,-3,4,-4,5,-5]

When we used >>= with Maybe, the monadic value was fed into the function while taking care of possible failures. Here, it takes care of non-determinism for us. [3,4,5] is a non-deterministic value and we feed it into a function that returns a non-deterministic value as well. The result is also non-deterministic, and it features all the possible results of taking elements from the list [3,4,5] and passing them to the function \x -> [x,-x]. This function takes a number and produces two results: one negated and one that’s unchanged. So when we use >>= to feed this list to the function, every number is negated and also kept unchanged. The x from the lambda takes on every value from the list that’s fed to it.

To see how this is achieved, we can just follow the implementation. First, we start off with the list [3,4,5]. Then, we map the lambda over it and the result is the following: [[3,-3],[4,-4],[5,-5]].

The lambda is applied to every element and we get a list of lists. Finally, we just flatten the list and voila! We’ve applied a non-deterministic function to a non-deterministic value!

Non-determinism also includes support for failure. The empty list [] is pretty much the equivalent of Nothing, because it signifies the absence of a result. That’s why failing is just defined as the empty list. The error message gets thrown away. Let’s play around with lists that fail:

Prelude> [] >>= \x -> ["bad","mad","rad"]
[]
Prelude> [1,2,3] >>= \x -> []
[]

In the first line, an empty list is fed into the lambda. Because the list has no elements, none of them can be passed to the function and so the result is an empty list. This is similar to feeding Nothing to a function. In the second line, each element gets passed to the function, but the element is ignored and the function just returns an empty list. Because the function fails for every element that goes in it, the result is a failure.

Just like with Maybe values, we can chain several lists with >>=, propagating the non-determinism:

Prelude> [1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch)
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

The list [1,2] gets bound to n and ['a','b'] gets bound to ch. Then, we do return (n,ch) (or [(n,ch)]), which means taking a pair of (n,ch) and putting it in a default minimal context. In this case, it’s making the smallest possible list that still presents (n,ch) as the result and features as little non-determinism as possible. Its effect on the context is minimal. What we’re saying here is this: for every element in [1,2], go over every element in ['a','b'] and produce a tuple of one element from each list.

Generally speaking, because return takes a value and wraps it in a minimal context, it doesn’t have any extra effect (like failing in Maybe or resulting in more non-determinism for lists) but it does present something as its result.

When you have non-deterministic values interacting, you can view their computation as a tree where every possible result in a list represents a separate branch.

Here’s the previous expression rewritten in do notation:

ltu.hs

listOfTuples :: [(Int,Char)]
listOfTuples = do
  n <- [1,2]
  ch <- ['a','b']
  return (n,ch)
Prelude> :l ltu
[1 of 1] Compiling Main             ( ltu.hs, interpreted )
Ok, modules loaded: Main.
*Main> listOfTuples
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

This makes it a bit more obvious that n takes on every value from [1,2] and ch takes on every value from ['a','b']. Just like with Maybe, we’re extracting the elements from the monadic values and treating them like normal values and >>= takes care of the context for us. The context in this case is non-determinism.

Using lists with do notation really reminds me of something we’ve seen before. Check out the following piece of code:

*Main> [ (n,ch) | n <- [1,2], ch <- ['a','b'] ]
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

Yes! List comprehensions! In our do notation example, n became every result from [1,2] and for every such result, ch was assigned a result from ['a','b'] and then the final line put (n,ch) into a default context (a singleton list) to present it as the result without introducing any additional non-determinism. In this list comprehension, the same thing happened, only we didn’t have to write return at the end to present (n,ch) as the result because the output part of a list comprehension did that for us.

In fact, list comprehensions are just syntactic sugar for using lists as monads. In the end, list comprehensions and lists in do notation translate to using >>= to do computations that feature non-determinism.

List comprehensions allow us to filter our output. For instance, we can filter a list of numbers to search only for that numbers whose digits contain a 7:

*Main> [ x | x <- [1..50], '7' `elem` show x ]
[7,17,27,37,47]

We apply show to x to turn our number into a string and then we check if the character '7' is part of that string. Pretty clever. To see how filtering in list comprehensions translates to the list monad, we have to check out the guard function and the MonadPlus type class. The MonadPlus type class is for monads that can also act as monoids. Here’s its definition:

class Monad m => MonadPlus m where
  mzero :: m a
  mplus :: m a -> m a -> m a

mzero is synonymous to mempty from the Monoid type class and mplus corresponds to mappend. Because lists are monoids as well as monads, they can be made an instance of this type class:

instance MonadPlus [] where
  mzero = []
  mplus = (++)

For lists mzero represents a non-deterministic computation that has no results at all — a failed computation. mplus joins two non-deterministic values into one. The guard function is defined like this:

gu.hs

class Monad m => MonadPlus m where
  mzero :: m a
  mplus :: m a -> m a -> m a

instance MonadPlus [] where
  mzero = []
  mplus = (++)

guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero
guard :: (MonadPlus m) => Bool -> m ()
guard True = return ()
guard False = mzero

It takes a boolean value and if it’s True, takes a () and puts it in a minimal default context that still succeeds. Otherwise, it makes a failed monadic value. Here it is in action:

ghci> guard (5 > 2) :: Maybe ()
Just ()
ghci> guard (1 > 2) :: Maybe ()
Nothing
ghci> guard (5 > 2) :: [()]
[()]
ghci> guard (1 > 2) :: [()]
[]

Per qualche motivo che non ho capito non riesco a riprodurre i risultati precedenti.

Looks interesting, but how is it useful? In the list monad, we use it to filter out non-deterministic computations. Observe:

*Main> :l gu
[1 of 1] Compiling Main             ( gu.hs, interpreted )
Ok, modules loaded: Main.
*Main> [1..50] >>= (\x -> guard ('7' `elem` show x) >> return x)
[7,17,27,37,47]

The result here is the same as the result of our previous list comprehension. How does guard achieve this? Let’s first see how guard functions in conjunction with >>:

*Main> guard (5 > 2) >> return "cool" :: [String]
["cool"]
*Main> guard (1 > 2) >> return "cool" :: [String]
[]

If guard succeeds, the result contained within it is an empty tuple. So then, we use >&gt; to ignore that empty tuple and present something else as the result. However, if guard fails, then so will the return later on, because feeding an empty list to a function with >>= always results in an empty list. A guard basically says: if this boolean is False then produce a failure right here, otherwise make a successful value that has a dummy result of () inside it. All this does is to allow the computation to continue.

Here’s the previous example rewritten in do notation:

sevensOnly :: [Int]
sevensOnly = do
  x <- [1..50]
  guard ('7' `elem` show x)
  return x

Ovviamente devo caricare la definizione di guard.

*Main> :l sevensOnly
[1 of 1] Compiling Main             ( sevensOnly.hs, interpreted )
Ok, modules loaded: Main.
*Main> sevensOnly
[7,17,27,37,47]

Had we forgotten to present x as the final result by using return, the resulting list would just be a list of empty tuples. Here’s this again in the form of a list comprehension:

*Main> [ x | x <- [1..50], '7' `elem` show x ]
[7,17,27,37,47]

So filtering in list comprehensions is the same as using guard.

Seguire Miran alle volte –proprio come oggi 👽

😐