you tube neyra mafer cosas chicas haskell ghc

haskell - tube - ¿Cómo puedo hacer que mi regla se dispare?



mafer neyra cosas de chicas (1)

Estoy trabajando en las reglas de fusión de fromListN para fromListN en Data.Primitive.Array , y estoy un poco atascado. La función se ve así:

fromListNArray :: Int -> [a] -> Array a fromListNArray !n l = createArray n fromListN_too_short $ /mi -> let go i (x:xs) | i < n = writeArray mi i x >> go (i+1) xs | otherwise = fromListN_too_long go i [] = unless (i == n) fromListN_too_short in go 0 l {-# NOINLINE fromListNArray #-}

fromListN_too_short y fromListN_too_long son solo llamadas de error.

Mis reglas de reescritura son

{-# RULES "fromListNArray/foldr" [~1] forall n xs. fromListNArray n xs = createArray n fromListN_too_short $ /mary -> foldr (fillArray_go n mary) (fillArray_stop n) xs 0 "fillArrayN/list" [1] forall n mary xs i. foldr (fillArray_go n mary) (fillArray_stop n) xs i = fillArrayN n mary xs i #-}

donde se definen los ayudantes

fillArrayN :: Int -> MutableArray s a -> [a] -> Int -> ST s () fillArrayN !n !mary xs0 !i0 = go i0 xs0 where go i (x:xs) | i < n = writeArray mary i x >> go (i+1) xs | otherwise = fromListN_too_long go i [] = unless (i == n) fromListN_too_short {-# NOINLINE fillArrayN #-} fillArray_go :: Int -> MutableArray s a -> a -> (Int -> ST s ()) -> Int -> ST s () fillArray_go !n !mary = /x r i -> if i < n then writeArray mary i x >> r (i + 1) else fromListN_too_long {-# INLINE CONLIKE [0] fillArray_go #-} fillArray_stop :: Int -> Int -> ST s () fillArray_stop !n = /i -> unless (i == n) fromListN_too_short {-# INLINE [0] fillArray_stop #-}

La primera regla de reescritura parece hacerlo bien. La segunda regla de la escritura es el problema. Parece que nunca puedo hacer que se dispare. ¿Alguien puede ofrecer una sugerencia?

Nota: Sé que podría fusionarme directamente con build y build para evitar tener que responder, pero ... no es una visión bonita.


El principal problema parece ser un error de mi parte. En

"fillArrayN/list" [1] forall n mary xs i. foldr (fillArray_go n mary) (fillArray_stop n) xs i = fillArrayN n mary xs i

foldr es Data.Foldable.foldr , que es un método de clase y por lo tanto no funciona en el LHS de una regla. Solucionar este problema hace que la regla de reescritura funcione en casos simples.

Desafortunadamente, cuando fromListNArray fusiona con el fromListNArray (que suele ocurrir cuando se aplica a las listas adjuntas), la regla no se activa por otra razón. GHC crea una función para fillArray_go n mary , y no la fillArray_go n mary . Todavía no entiendo por qué sucede esto.