Haskell и «петля» с защитой

У меня проблема с 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 возвращает мне что-то странное. функция make_list возвращает список строк, например: [['_','_'],['*','_'],['_','*'],['*','*']].

Я хочу, чтобы loop получил первый элемент этого списка, вставил его в качестве аргумента в sprawdz_kombinacje2. Если эта функция вернет False, это будет чистый элемент из списка. В противном случае функция petla должна вернуть строку, например: ['_','*'].

Проблема: когда я запускаю эту функцию в 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)

person Simon    schedule 29.06.2012    source источник
comment
Ваш код не работает. Я бы попытался исправить это, но имена переменных меня отталкивают. У вас гораздо больше шансов получить ответ, если ваши имена (1) короче и (2) на английском языке.   -  person Chris Taylor    schedule 30.06.2012
comment
Также, пожалуйста, уточните, что именно вы просите, и определите функции, для которых вы не показали код, которые не являются стандартными функциями.   -  person Squazic    schedule 30.06.2012
comment
А пока я скажу, что я не думаю, что вы понимаете, что означает return в функциональном языке, таком как Haskell.   -  person Squazic    schedule 30.06.2012


Ответы (2)


GHC и GHCi, как я уверен, вы знаете, были написаны в Глазго. Его первые несколько публичных выпусков принимали только код, написанный на шотландском языке. Например, использование монады RWS выглядело так:

import Guide.Monad.RWS

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

Авторам было довольно сложно локализовать его на английский язык. Поэтому я совершенно уверен, что пройдет несколько лет, прежде чем GHC сможет обрабатывать код на польском языке. Пшепрашам :(

person mergeconflict    schedule 30.06.2012
comment
Мне немного грустно, что мой ответ тролля получил больше голосов, чем настоящий ответ Дэниела. Тоже немного счастлив. - person mergeconflict; 30.06.2012
comment
Хм, а разве иерархические модули не добавлялись только после переноса на английский язык? - person Daniel Fischer; 30.06.2012

Сообщение от gci,

*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 в подписи).

person Daniel Fischer    schedule 29.06.2012