Parece divertido publicar algunas preguntas como respuesta. Este es divertido, en la interacción entre Applicative
y Traversable
, basado en sudoku.
(1) Considerar
data Triple a = Tr a a a
Construct
instance Applicative Triple
instance Traversable Triple
para que la instancia Applicative
hace "vectorización" y la instancia Traversable
trabaja de izquierda a derecha. No olvides construir una instancia adecuada de Functor
: comprueba que puedes extraerla de la instancia Applicative
o Traversable
. Puede encontrar
newtype I x = I {unI :: x}
útil para este último.
(2) Considérese
newtype (:.) f g x = Comp {comp :: f (g x)}
Demostrar que
instance (Applicative f, Applicative g) => Applicative (f :. g)
instance (Traversable f, Traversable g) => Traversable (f :. g)
definen ahora
type Zone = Triple :. Triple
Supongamos que representan una Board
como una zona vertical de zonas horizontales
type Board = Zone :. Zone
Muestre cómo reorganizarlo como una zona horizontal de zonas verticales, y como un cuadrado de cuadrados, utilizando la funcionalidad traverse
.
(3) Considere
newtype Parse x = Parser {parse :: String -> [(x, String)]} deriving Monoid
o alguna otra construcción adecuada (teniendo en cuenta que el comportamiento de la biblioteca para Monoid
| Quizás | es inapropiada).Construir
instance Applicative Parse
instance Alternative Parse -- just follow the `Monoid`
e implementar
ch :: (Char -> Bool) -> Parse Char
que consume y ofrece un personaje si es aceptada por un predicado dado.
(4) Implementar un analizador que consume cualquier cantidad de espacios en blanco, seguido de un solo dígito (0 representa espacios en blanco)
square :: Parse Int
Uso pure
y traverse
para construir
board :: Parse (Board Int)
(5) Considere los functors constantes
newtype K a x = K {unK :: a}
y constru ct
instance Monoid a => Applicative (K a)
a continuación, utilizar traverse
para implementar
crush :: (Traversable f, Monoid b) => (a -> b) -> f a -> b
Construct newtype
envolturas para Bool
expresar sus estructuras monoides conjuntivos y disyuntivos. Use crush
para implementar versiones de any
y all
que funcionen para cualquier funcionador Traversable
.
(6) Implementar
duplicates :: (Traversable f, Eq a) => f a -> [a]
el cálculo de la lista de valores que se producen más de una vez. (No es completamente trivial.) (Hay una bonita manera de hacer esto utilizando el cálculo diferencial, pero eso es otra historia.)
(7) Implementar
complete :: Board Int -> Bool
ok :: Board Int -> Bool
el que comprobar si una tabla es (1) completo solamente de dígitos en [1..9] y (2) desprovistos de duplicados en cualquier fila, columna o casillero.
No puedo sugerir ejercicios, pero podría ver los funtores aplicativos que no son mónadas (una pregunta crucial parece ser "¿por qué diseñar un functor aplicativo cuando es menos poderoso que una mónada?"). El aplicativo de errores múltiples (en Paterson y McBride) es uno, también hay analizadores de Doaitse Swierstra, uno de animación _Active_ en Andy Gill y Kevin Matledge's Chalkboard y creo que Andy Gill y sus colegas 'Kansas Lava se basan en un funcionador aplicativo. –