tag name lista keywords list haskell infinite applicative

list - name - Demostrando igualdad de arroyos



name keywords (3)

¿Por qué necesitas coinducción? Sólo induct.

pure f <*> pure a = pure (f a)

También se puede escribir (es necesario probar la igualdad de izquierda y derecha)

N f [(pure f)] <*> N a [(pure a)] = N (f a) [(pure (f a))]

lo que le permite desactivar un término a la vez. Eso te da tu inducción.

Tengo un tipo de datos

data N a = N a [N a]

De rosales y instancia aplicativa.

instance Applicative N where pure a = N a (repeat (pure a)) (N f xs) <*> (N a ys) = N (f a) (zipWith (<*>) xs ys)

y necesidad de probar las leyes aplicativas para ello. Sin embargo, lo puro crea árboles infinitamente profundos e infinitamente ramificados. Así, por ejemplo, al probar la ley del homomorfismo.

pure f <*> pure a = pure (f a)

Pensé que demostrando la igualdad.

zipWith (<*>) (repeat (pure f)) (repeat (pure a)) = repeat (pure (f a))

por la aproximación (o toma) lemma funcionaría. Sin embargo, mis intentos llevan a "círculos viciosos" en el paso inductivo. En particular, reduciendo

approx (n + 1) (zipWith (<*>) (repeat (pure f)) (repeat (pure a))

da

(pure f <*> pure a) : approx n (repeat (pure (f a)))

donde aprox es la función de aproximación. ¿Cómo puedo probar la igualdad sin una prueba coinductiva explícita?


El siguiente es un bosquejo de algo que creo que funciona y se mantiene en el nivel de la sintaxis programática y el razonamiento ecuacional.

La intuición básica es que es mucho más fácil razonar sobre la repeat x que sobre una transmisión (y, lo que es peor, una lista) en general.

uncons (repeat x) = (x, repeat x) zipWithAp xss yss = let (x,xs) = uncons xss (y,ys) = uncons yss in (x <*> y) : zipWithAp xs ys -- provide arguments to zipWithAp zipWithAp (repeat x) (repeat y) = let (x'',xs) = uncons (repeat x) (y'',ys) = uncons (repeat y) in (x'' <*> y'') : zipWithAp xs ys -- substitute definition of uncons... zipWithAp (repeat x) (repeat y) = let (x,repeat x) = uncons (repeat x) (y,repeat y) = uncons (repeat y) in (x <*> y) : zipWithAp (repeat x) (repeat y) -- remove now extraneous let clause zipWithAp (repeat x) (repeat y) = (x <*> y) : zipWithAp (repeat x) (repeat y) -- unfold identity by one step zipWithAp (repeat x) (repeat y) = (x <*> y) : (x <*> y) : zipWithAp (repeat x) (repeat y) -- (co-)inductive step zipWithAp (repeat x) (repeat y) = repeat (x <*> y)


Yo usaría la propiedad universal de los despliegues (ya que se repiten y se despliegan adecuadamente). Hay una discusión relacionada en mi blog . Pero es posible que también le gusten los artículos de Ralf Hinze sobre puntos de ICFP2008 únicos ICFP2008 (y el documento de JFP posterior).

(Solo verificando: ¿todos tus rosales son infinitamente anchos e infinitamente profundos? Supongo que las leyes no se sostendrán de otra manera).