yourself sintaxis learn intercalate functions example haskell types

haskell - sintaxis - Tipo de error con los tipos de rango 2 y composición de funciones



sintaxis haskell (2)

Aquí hay algunos pragmas y algunas importaciones:

{-# LANGUAGE ScopedTypeVariables #-} import Control.Monad.ST import Data.Array.ST import Data.Array

Ahora aquí está mi problema. El siguiente código typechecks:

foo :: forall a. a -> [a] foo x = elems $ runSTArray $ do newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int a)

Sin embargo, cuando reemplazo $ con la composición:

foo :: forall a. a -> [a] foo x = elems . runSTArray $ do newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int a)

Me sale este error:

Couldn''t match expected type `forall s. ST s (STArray s i0 e0)'' with actual type `ST s0 (STArray s0 Int a)'' In the expression: newListArray (1, 10) (replicate 10 x) :: ST s (STArray s Int a) In the second argument of `($)'', namely `do { newListArray (1, 10) (replicate 10 x) :: ST s (STArray s Int a) }'' In the expression: elems . runSTArray $ do { newListArray (1, 10) (replicate 10 x) :: ST s (STArray s Int a) }

Lo que es werid es, si le doy a la composición de la función su propio nombre, entonces se vuelve a tipear:

elemSTArray = elems . runSTArray foo :: forall a. a -> [a] foo x = elemSTArray $ do newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int a)

No estoy seguro de lo que está pasando aquí. Esperaría que la segunda pieza de código sea chequeada muy bien. Y no entiendo por qué se vuelve a tipear si le doy a la función compuesta su propio nombre.

Esta es una versión simplificada de algún código que tuve que se rompió al actualizar de GHC 6.2 a 7 y estoy tratando de entender por qué sucede esto ahora. ¡Gracias por ayudar!


Como ya indicas en el título de tu publicación, el problema tiene que ver con que runSTArray tenga un tipo polimórfico de rango 2.

runSTArray :: Ix i => (forall s. ST s (STArray s i e)) -> Array i e

Con

elems :: Ix i => Array i e -> [e]

y

($) :: (a -> b) -> a -> b

escribir runSTArray $ ... significa que la variable de tipo a en el esquema de tipo de ($) necesita ser instanciada con un tipo polimórfico en lugar de un tipo monomórfico. Esto requiere el llamado polimorfismo impredicativo. La forma en que GHC implementa el polimorfismo impredicativo se explica en el documento de ICFP 2008 de Dimitrios Vytiniotis, Stephanie Weirich y Simon Peyton Jones: FPH: Polimorfismo de primera clase para Haskell . En resumidas cuentas, si bien la FPH a menudo le proporciona el comportamiento que espera, la capacidad de escritura a veces no se conserva en transformaciones simples como las que describe en su pregunta: consulte la Sección 6.2 del documento mencionado anteriormente.


Stefan me ganó la respuesta, lo difícil es que no es el $ vs. entre elems y runSTArray ese es el problema, es el $ following runSTArray . Como something $ rankNthing es tan común, hay una parte inteligente (se me olvidan los detalles) que intenta dejar que lo hagas como un caso de esquina. Pero de alguna manera, usar la composición más temprano evita esto. La ubicación del problema se demuestra por el hecho de que el siguiente tipo de verificación:

foo x = (elems . runSTArray) ( (newListArray (1,10) (replicate 10 x) :: ST s (STArray s Int String)))

No estoy seguro de que esto sea un error per se, pero sin duda es un comportamiento inesperado al que vale la pena crear un ticket, ya que aún podría haber un algoritmo mejor para detectar casos como el que proporcionó.