Simon
Simon

Reputation: 1117

Haskell and the 'loop' with guard

I've problem with Haskell. I've got a simple code:

petla szerokosc wysokosc pozycje = do
let plansza_x = oznacz_pola_dookola_jako_miejsca_na_skarby_wiele 
            pozycje
        (utworz_plansze pozycje szerokosc wysokosc) 
        szerokosc
 let x = make_list $ zlicz_x plansza_x
 guard ((sprawdz_kombinacje2 plansza_x pozycje (head x) szerokosc wysokosc) == True)
 x

The parameters are good, but the GHCI returns my something strange. function make_list returns the list of Strings, for example: [['_','_'],['*','_'],['_','*'],['*','*']].

I want the loop get the first element of this list, paste it as an argument into the sprawdz_kombinacje2. If that function return False it will be get net element from the list. Otherwise the function petla should return the String, for example: ['_','*'].

The problem: when I run this function in GHCI, it returns me empty list, but it shouldn't:

*Main> petla 2 2 [(1,1,1)]
[]

But, when I added return to the last line:

petla szerokosc wysokosc pozycje = do
let plansza_x = oznacz_pola_dookola_jako_miejsca_na_skarby_wiele 
            pozycje
        (utworz_plansze pozycje szerokosc wysokosc) 
        szerokosc
 let x = make_list $ zlicz_x plansza_x
 guard ((sprawdz_kombinacje2 plansza_x pozycje (head x) szerokosc wysokosc) == True)
 return x

and I compiled it, and run this function with the same arguments like before, the GHCI returns me:

*Main> petla 2 2 [(1,1,1)]

<interactive>:1:0:
    Ambiguous type variable `m' in the constraint:
      `Control.Monad.MonadPlus m'
         arising from a use of `petla' at <interactive>:1:0-18
    Probable fix: add a type signature that fixes these type variable(s)

Upvotes: 1

Views: 921

Answers (2)

mergeconflict
mergeconflict

Reputation: 8276

GHC and GHCi were, as I'm sure you know, written in Glasgow. Its first several public releases only accepted code written in Scots. For example, using the RWS monad looked like:

import Guide.Monad.RWS

ensaumple :: RWS Int [Int] Int ()
ensaumple = dae
  env <- aks
  s   <- git
  lat s' = s + env
  pit s'
  clype [s']

The authors had quite the challenging time localizing it to English. So I'm quite certain it will be some years before GHC is able to handle code in Polish. Przepraszam :(

Upvotes: 8

Daniel Fischer
Daniel Fischer

Reputation: 183968

The message from ghci,

*Main> petla 2 2 [(1,1,1)]

<interactive>:1:0:
    Ambiguous type variable `m' in the constraint:
      `Control.Monad.MonadPlus m'
         arising from a use of `petla' at <interactive>:1:0-18
    Probable fix: add a type signature that fixes these type variable(s)

means that the expression petla 2 2 [(1,1,1)] has the inferred type

MonadPlus m => m sometype

The MonadPlus constraint on m comes from the use of guard. But ghci has no way to know which instance of MonadPlus it should use here. In programmes, that can usually be inferred from the calling context, but at the ghci prompt, there is no calling context. Hence you have to tell ghci which MonadPlus instance to use. You can do that by providing a type signature for petla in the file where it is defined (or, if it's defined at the prompt, by giving a type signature there along with the definition), or by providing a type signature for the expression entered at the ghci prompt, for example

ghci> petla 2 2 [(1,1,1)] :: [sometype]

(replace sometype with an appropriate monomorphic type; if the result of make_list is, as indicated by the post, [[String]], that would replace sometype in the signature).

Upvotes: 5

Related Questions