Haskell和守卫的'循环'

Sim*_*mon 1 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
Run Code Online (Sandbox Code Playgroud)

参数很好,但GHCI让我觉得奇怪.function make_list返回字符串列表,例如:[['_','_'],['*','_'],['_','*'],['*','*']].

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

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

*Main> petla 2 2 [(1,1,1)]
[]
Run Code Online (Sandbox Code Playgroud)

但是,当我添加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
Run Code Online (Sandbox Code Playgroud)

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

mer*_*ict 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']
Run Code Online (Sandbox Code Playgroud)

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

  • 我有点难过,我的巨魔答案比丹尼尔的真实答案更有赞成.也有点开心. (5认同)

Dan*_*her 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)
Run Code Online (Sandbox Code Playgroud)

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

MonadPlus m => m sometype
Run Code Online (Sandbox Code Playgroud)

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

ghci> petla 2 2 [(1,1,1)] :: [sometype]
Run Code Online (Sandbox Code Playgroud)

(替换sometype为适当的单形类型;如果结果make_list是,如帖子所示,[[String]]sometype在签名中替换).