Haskell和守卫的'循环'

时间:2012-06-29 19:59:00

标签: haskell guard

我遇到了Haskell的问题。我有一个简单的代码:

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

参数很好,但GHCI让我发现了一些奇怪的东西。 function make_list返回字符串列表,例如:[['_','_'],['*','_'],['_','*'],['*','*']]

我希望loop获取此列表的第一个元素,将其作为参数粘贴到sprawdz_kombinacje2中。如果该函数返回False,它将从列表中获取net元素。否则函数petla应返回String,例如:['_','*']

问题:当我在GHCI中运行此函数时,它返回空列表,但它不应该:

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

但是,当我将return添加到最后一行时:

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

我编译了它,并使用与之前相同的参数运行此函数,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)

2 个答案:

答案 0 :(得分:8)

我相信GHC和GHCi是在格拉斯哥写的。它的前几个公开发布只接受用苏格兰语编写的代码。例如,使用RWS monad看起来像:

import Guide.Monad.RWS

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

作者在将其本地化为英语时非常具有挑战性。所以我很确定GHC能够处理波兰语代码需要几年的时间。 Przepraszam :(

答案 1 :(得分:5)

来自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)

表示表达式petla 2 2 [(1,1,1)]具有推断类型

MonadPlus m => m sometype

MonadPlus上的m约束来自guard的使用。但ghci无法知道它应该使用哪个MonadPlus实例。在程序中,通常可以从调用上下文推断出,但在ghci提示符下,没有调用上下文。因此,您必须告诉ghci使用哪个MonadPlus实例。您可以通过在定义它的文件中为petla提供类型签名(或者,如果在提示符处定义,通过在其中提供类型签名以及定义),或者通过提供类型签名来实现对于在ghci提示符下输入的表达式,例如

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

(将sometype替换为适当的单形类型;如果make_list的结果是[[String]],则会替换签名中的sometype )。