Sono interessato a sapere se esiste una funzione di libreria standard che esegue ciò che non riesco a trovare.
È facile mancare a causa della classe di tipo, ma look at Control.Arrow
. I normali Arrow
s non possono essere ritentati o applicati, quindi i combinatori Arrow
sono esenti da punti per necessità. Se li siete specializzati a (->)
, troverete quello che si desidera è questo:
(&&&) :: (Arrow a) => a b c -> a b c' -> a b (c, c')
Ci sono altre, funzioni simili, come ad esempio l'operazione equivalente per Either
, che si è specializzata a (->)
assomiglia a questo:
(|||) :: (a -> c) -> (b -> c) -> Either a b -> c
Che è uguale a either
.
Per curiosità, mi piacerebbe riscrivere questa funzione in stile point-free, ma sto avendo un sacco di problemi con esso.
Dal momento che si sta duplicando un ingresso, è necessario un modo di fare che pointfree - il modo più comune è tramite l'istanza Applicative
o Monad
per (->)
, per esempio \f g ->(,)
< $ > f < *> g
. Questo è essenzialmente un monad implicito, in linea Reader
, e l'argomento che viene diviso è il valore "ambiente". Usando questo approccio, join f x
diventa f x x
, pure
o return
diventano const
, fmap
diventa (.)
, e (<*>)
diventa il S combinator\f g x -> f x (g x)
.
fonte
2013-01-16 03:31:14
Grazie per la risposta concisa, e grazie per la segnalazione a me pointfree. – bshourd