Tengo un programa que funciona. Sin embargo, no estaba exactamente seguro de por qué se estaba compilando.

Esta es mi función principal

module Main where

import System.Environment
import Cover5

main :: IO ()
main = do
         args <- getArgs
         let numGames = if null args then 13 else read $ head args
         putStrLn $ "Making picks for " ++ show numGames ++ " games."
         print $ run numGames

Donde la función run tiene la firma run :: Int -> RVar [(Int, Char)].

Lo que es confuso es que no hay una instancia de Show para RVar [(Int,Char)], así que supongo que no debería compilarse, pero lo hace (consulte Travis-CI build y la fuente relacionada para eso confirmación de Main.hs). Puedo forzar una advertencia con este comando:

cabal build --ghc-options="-fforce-recomp -fno-code"
Preprocessing executable 'cover5' for cover5-0.1.0.1...
[1 of 2] Compiling Cover5           ( src/Cover5.hs, nothing )
[2 of 2] Compiling Main             ( src/Main.hs, nothing )

src/Main.hs:13:10: error:
    • No instance for (Show (RVar [(Int, Char)]))
        arising from a use of ‘print’
    • In a stmt of a 'do' block: print $ run numGames
      In the expression:
        do { args <- getArgs;
             let numGames = ...;
             putStrLn $ "Making picks for " ++ show numGames ++ " games.";
             print $ run numGames }
      In an equation for ‘main’:
          main
            = do { args <- getArgs;
                   let numGames = ...;
                   putStrLn $ "Making picks for " ++ show numGames ++ " games.";
                   .... }

Me gustaría "arreglar" esto y he seguido la guía de la pregunta Convertir Data.RVar.RVar [Char] a [Char]

Entonces agrego las importaciones apropiadas para StdRandom y runRVar y escribo las siguientes líneas

results <- runRVar (run numGames) StdRandom
putStrLn $ show results

Pero me estoy tropezando tratando de encontrar instancias de MonadRandom IO para mi uso:

src/Main.hs:13:21: error:
    • No instance for (MonadRandom IO) arising from a use of ‘runRVar’
    • In a stmt of a 'do' block:
        results <- runRVar (run numGames) StdRandom
      In the expression:
        do { args <- getArgs;
             let numGames = ...;
             putStrLn $ "Making picks for " ++ show numGames ++ " games.";
             results <- runRVar (run numGames) StdRandom;
             .... }
      In an equation for ‘main’:
          main
            = do { args <- getArgs;
                   let numGames = ...;
                   putStrLn $ "Making picks for " ++ show numGames ++ " games.";
                   .... }

Entonces dos preguntas:

  1. ¿Por qué se compila y funciona la versión original?
  2. ¿Qué me podría sugerir que haga para eliminar la advertencia y escribir esto "correctamente"?
0
Michael Welch 15 ene. 2017 a las 18:32
Supongo que un enfoque más fácil para mí (para solucionar esto) es convertir los pares (Int, Char) en cadenas dentro de la mónada RVar. Entonces me alinearía más de cerca con el problema en la pregunta vinculada.
 – 
Michael Welch
15 ene. 2017 a las 19:03
3
Eso no es una advertencia, es un error. La versión original no se compila. ¿Quizás ha ejecutado un ejecutable antiguo con una prueba trivial que todavía estaba por ahí?
 – 
leftaroundabout
15 ene. 2017 a las 19:19
1
OTOH, la versión runRVar debería compilarse, porque hay una instancia MonadRandom IO. A menos que algo esté muy roto con el entorno de su biblioteca ... ¿o quizás haya importado solo módulos "internos" que en realidad no exportan esa instancia? ¿Qué sucede si importa explícitamente Data.Random?
 – 
leftaroundabout
15 ene. 2017 a las 19:25
1
Ajá, Cover5 importa Data.Random.Show.Unsafe. ¿Por qué la gente sigue haciendo cosas explícitamente inseguras y luego viene aquí quejándose de que suceden cosas extrañas?
 – 
leftaroundabout
15 ene. 2017 a las 19:30
1
Data.Random es el módulo principal que necesita para hacer cosas de aleatoriedad. Es la interfaz pública de random-fu, por así decirlo. Data.RVar es simplemente la definición del tipo de datos llamado RVar , no un módulo que le brinda rutinas para trabajar con eso.
 – 
leftaroundabout
15 ene. 2017 a las 19:32

1 respuesta

La mejor respuesta

Las respuestas fueron proporcionadas por @leftaroundabout en los comentarios. Publicar una respuesta aquí para otras personas nuevas en Random en caso de que resulte útil

Primera pregunta Había escrito el programa original hace unos 3 años. No tenía idea de cómo imprimir los resultados de RVar s. Elegí usar Data.Random.Show.Unsafe. Aparentemente, este módulo proporciona una instancia de Show para RVar a. No lo recordaba.

Además, estaba exportando implícitamente todo desde mi módulo Cover5, por lo que el módulo principal cuyo código está arriba estaba importando esa instancia.

Entonces, es por eso que print estaba funcionando.

Segunda pregunta Las instancias están disponibles en Data.Random, que no estaba importando.

La razón por la que recibía errores pero pensaba que eran advertencias es porque cambié 2 (en realidad más de 2) cosas a la vez:

  1. Restringí lo que se exportó desde el módulo Cover5 para que la instancia Insegura de Show ya no se exportara
  2. Ejecuté la compilación con algunos argumentos que pensé que solo iban a mostrar más advertencias que una compilación tradicional.
0
Michael Welch 16 ene. 2017 a las 20:16