haskell pointfree

haskell - Ayuda en la comprensión de código de pointfree



(1)

Al jugar con Pointfree me presentaron un código que no puedo entender.

:pl map (/x -> x * x) [1..10] -- map (join (*)) [1..10]

Mi principal problema es que no entiendo cómo funciona la join aquí. Entiendo que ''elimina'' una capa de una envoltura monádica ( m (ma) a ma ). Me parece que se reduce a algo como [1..10] >>= (/x -> [x * x]) , pero realmente no entiendo cómo se introduce la "capa extra". Obtengo esa join x = x >>= id , pero luego sigo atascado en cómo "duplica" cada valor para que (*) obtenga dos argumentos. Esto me ha estado molestando durante aproximadamente media hora y me siento molesto conmigo mismo, porque siento que tengo todas las piezas del rompecabezas pero parece que no puedo encajarlas ...

PD No te preocupes, realmente no usaría esta versión de pointfree, esto es pura curiosidad y un intento de entender mejor a Haskell.


join usa la instancia de Monad para (->) a , como se define en Control.Monad.Instances . La instancia es similar a Reader , pero sin un contenedor explícito. Se define así:

instance Monad ((->) a) where -- return :: b -> (a -> b) return = const -- (>>=) :: (a -> b) -> (b -> a -> c) -> (a -> c) f >>= g = /x -> g (f x) x

Si ahora reduce la join usando esta instancia:

join (>>= id) flip (/f g x -> g (f x) x) (/a -> a) (/f x -> (/a -> a) (f x) x) (/f x -> f x x)

Como puede ver, la instancia para (->) a hace que se una a una función que aplica un argumento dos veces. Debido a esto, join (*) es simplemente /x -> x * x .