Passer en paramètre une fonction qui imprime un texte, l'exécutant après un nouvel état en Haskell

contremaître

Sur EDIT3, il y a un seul fichier avec le code presque complet.

https://github.com/agutie58/landOfLispInHaskell/blob/main/exampleLoLTextGameHaskell.hs

Et sur EDIT2 un exemple du jeu réel.

[ORIGINAL] J'ai une fonction "run" qui est basée sur un domaine, et une liste d'événements, si tous les événements sont traités, elle écoute les nouveaux événements, et s'il s'agit d'événements, elle en traite plusieurs. La majorité des événements modifie le Domaine :

data Domain =   Domain (String, World) deriving (Show)
data World = World {loc :: String, descSites :: [(Key,String)], mapSites :: [(Key, [Lloc])], objects:: [Key], siteObjects::[(Key,String)]}  deriving (Show)


run :: Domain -> [Event] -> IO ()
run dm [] = do
  events <- uiUpdate dm
  run dm events

run _ (EventExit:_) =
  return ()

run dm (e:es) =
  run (dmUpdate dm e) es

La partie sur laquelle je veux me concentrer est : "run (dmUpdate dm e) es". Le "dmUpdate dm e" renvoie un type Domain.

Un exemple de cette fonction dmUpdate qui fonctionne bien est (où look :: World -> Domain ; walk :: String -> World -> Domain; etc.) :

dmUpdate :: Domain -> Event  ->  Domain

dmUpdate (Domain v) (EventLook) =  look (snd v) 
                                               
dmUpdate (Domain v) (EventWalk direction) =  walk direction (snd v) 

dmUpdate dm _ _ = dm 

Je veux rendre (imprimer sur console) le résultat d'un nouveau domaine. Par exemple:

dmUpdate (Domain v) (EventLook) =  do let newDomain = look (snd v) 
                                          putStr (fst newDomain)
                                          newDomain

Mais cela ne fonctionne pas. J'essaie de calculer un nouvel état du monde, puis IO, puis j'essaie de renvoyer le newDomain en tant que paramètre.

J'ai pensé passer une fonction comme ça :

run dm (e:es) =
  run (dmUpdate dm e renderMsg) es
  where renderMsg txt = (putStr txt) >> (hFlush stdout)

.. Pour faire quelque chose comme :

-- dmUpdate :: dmUpdate :: Domain -> Event -> (String -> IO ()) -> IO () -> Domain
dmUpdate (Domain v) (EventLook) (renderMsg) =  let newDomain = look (snd v) 
                                               renderMsg (fst newDomain)

Mais ne fonctionne pas.

Des idées !? Merci d'avance!

EDIT1 : j'ai aussi essayé :

  dmUpdate :: Domain -> Event  -> IO Domain
    dmUpdate (Domain v) (EventLook) =  do let newDomain = look (snd v) 
                                          putStr (fst newDomain)
                                          newDomain
                                                                                        
    
    dmUpdate dm _ _ = () dm 

... mais j'ai ce message :

[2 of 2] Compiling Main             ( textGameMain.hs, interpreted )

textGameMain.hs:25:1: error:
    Equations for ‘dmUpdate’ have different numbers of arguments
      textGameMain.hs:(25,1)-(27,47)
      textGameMain.hs:33:1-23
   |
25 | dmUpdate (Domain v) (EventLook) =  do let newDomain = look (snd v) 
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...

textGameMain.hs:70:8: error:
    • Couldn't match expected type ‘Domain’
                  with actual type ‘IO Domain’
    • In the first argument of ‘run’, namely ‘(dmUpdate dm e)’
      In the expression: run (dmUpdate dm e) es
      In an equation for ‘run’: run dm (e : es) = run (dmUpdate dm e) es
   |
70 |   run (dmUpdate dm e ) es

Alors, j'ai essayé de changer de run :

run dm (e:es) =
  run () (dmUpdate dm e ) es

Mais je n'ai pas réussi à le faire fonctionner.. :S

EDIT2 : Donc, mon code fait ça (il est basé sur "Land of Lisp", et c'est une adaptation à Haskell) :

*Main> main WORLD> regardez vous êtes dans le salon. un sorcier ronfle bruyamment sur le canapé. Il y a une porte vers l'ouest à partir d'ici. Il y a une échelle qui monte à l'étage d'ici. Vous voyez un whisky par terre. Vous voyez un seau sur le sol.

MONDE> marche vers l'ouest MONDE> regarde, tu es dans un beau jardin. il y a un puits devant vous. Il y a une porte qui va vers l'est à partir d'ici. Vous voyez une grenouille sur le sol. Vous voyez une chaîne sur le sol.

EDIT3 : (code complet - en fait j'ai regroupé deux fichiers en un seul pour plus de simplicité... il existe une autre manière d'ajouter un fichier !?) https://github.com/agutie58/landOfLispInHaskell/blob/main/exampleLoLTextGameHaskell. hs

ghci exampleLoLTextGameHaskell.hs main

(.. et puis, quelque chose à EDIT2 ..)

LudvigH

Votre code est loin d'être complet, contient beaucoup de - pour votre question - des parties inutiles. J'ai copié votre code, simplifié un peu et fait quelques devinettes. Voici ma version "fixe".

module Tmp where
import Text.Read (readMaybe)

{-| Be clear about your types. Introducing type alisases helps others read your code.
 I simply guessed that the string-part of the Domain is the UI state -}
type UIState = String
data Domain = Domain (UIState,World) deriving Show
data World = World {loc:: Int} deriving Show

-- | I Have only implemented two directions, so that this example is easy to work with.
data Dir = L | R deriving (Read, Show)

{- | These were the event types that you had in your code. I elaborated them a little. 
By using the "deriving (Read)" we get a low-code input mechanism, but you should probalbly write
your own input parser
-} 
data Event = EventExit | EventWalk Dir| EventLook deriving (Read)

-- | The run-loop now has TWO steps. Render UI and get new events. Process events. Finally recurse.
run :: Domain -> [Event] -> IO ()
run dm [] = uiUpdate dm >> getAction >>= run dm
run _ (EventExit:_) = return ()
run dm (e:es) = run (dmUpdate dm e) es

{-| Update the domain when a single event acts on it -}
dmUpdate :: Domain -> Event -> Domain
dmUpdate (Domain v) (EventLook) =  look (snd v) 
dmUpdate (Domain v) (EventWalk direction) =  walk direction (snd v)
dmUpdate dm _ = dm

look w = Domain ("You are at coordinate " ++ (show .loc $ w), w)
walk L w@World{loc=l}= Domain ("You went left", w{loc=l-1})
walk R w@World{loc=l} = Domain  ("You went right", w{loc=l+1})

{-| Present the "output" that the domain holds for us -}
uiUpdate :: Domain -> IO ()
uiUpdate dm = do
    let Domain (usState,s) = dm
    putStrLn usState

{-| Ask user for input. Only a single event is collected. -}
getAction :: IO [Event]
getAction = do
    putStrLn "What do you want to do? Choose between EventExit | EventWalk R | EventWalk L | EventLook"
    act <- readMaybe <$> getLine
    case act of 
        Nothing -> putStrLn "Not a valid action" >> getAction
        Just evt -> pure [evt]


main :: IO ()
main = run  (Domain ("",World 0)) [EventLook]

Enfin, vous voudrez peut-être examiner StateT afin de pouvoir faire abstraction de l'objet Domain qui est transmis tout le temps. Mais cela sort du cadre de cette question, je suppose.

Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.

En cas d'infraction, veuillez [email protected] Supprimer.

modifier le
0

laisse moi dire quelques mots

0commentaires
connexionAprès avoir participé à la revue

Articles connexes

TOP liste

  1. 1

    Créer un dictionnaire à partir d'une liste de clés et de plusieurs listes de valeurs en Python

  2. 2

    Spring Reactive: java.io.IOException: Une connexion établie a été abandonnée par le logiciel de votre machine hôte, lorsque je ferme la connexion

  3. 3

    Créer un arbre binaire à partir d'une liste de listes en Python

  4. 4

    Comment obtenir l'image actuelle dans un flux en direct avec python et opencv ?

  5. 5

    Comment puis-je ajouter une entrée utilisateur à une liste de contrôle, puis la placer dans une étiquette?

  6. 6

    Comment séparer les cartes qui se chevauchent les unes des autres en utilisant python opencv?

  7. 7

    how to convert the type of each element in a list to a list in python

  8. 8

    impossible de charger le fichier ou l'assembly 'microsoft.sqlserver.management.sdk.sfc version = 11.0.0.0

  9. 9

    Définition de la fonction de programmation Visual Studio C

  10. 10

    La méthode GET n'est pas prise en charge pour cette route. Méthodes prises en charge : POST

  11. 11

    impossible d'ouvrir un nouvel onglet dans react, ajoute localhost: 3000 sur le lien?

  12. 12

    Comment trouver efficacement les valeurs min et max des variables dans ce système de contraintes?

  13. 13

    comment créer un champ de recherche dans gridview sans utiliser le modèle de recherche

  14. 14

    Trouver l'intersection et l'union de deux rectangles

  15. 15

    Détection d'affiche dans OpenCV?

  16. 16

    Comment changer la couleur de la police dans R?

  17. 17

    comment supprimer "compte de connexion google" à des fins de développement - actions sur google

  18. 18

    comment le contrôle de tableau javascript devrait-il être

  19. 19

    Référencement des assemblys de structure .net 4.7 dans la solution .net core 2

  20. 20

    J'ai besoin de savoir si ces deux phrases sont les mêmes en programmation

  21. 21

    SignalR cesse de fonctionner après un certain temps

chaudétiquette

Archive