2014-10-16 6 views
-1

Эти участки кода отношение к моей проблеме:Неполный ошибка в функции

type Pos = (Int, Int) 
type Block = [Maybe Int] 
type Sudoku = [[Maybe Int]] 

blank :: Sudoku -> Pos 
blank sud = let k = ((whichRow sud) -1) in 
      let n = ((whereIsNothing (head (drop (k-1) (rows sud)))) -1) in 
      (k, n) 


whichRow :: Sudoku -> Int 
whichRow sud = whichRow' sud 0 
    where 
    whichRow' (Sudoku [])  i = i 
    whichRow' (Sudoku (r:rs)) i = if isNothingPresent r 
     then 1 
     else whichRow' (Sudoku rs) (i+1) 


whereIsNothing :: Block -> Int 
whereIsNothing (x:xs) = if x == Nothing then 1 else 1 + whereIsNothing xs 


isNothingPresent :: Block -> Bool 
isNothingPresent b = not (Nothing `notElem` b) 

То, что я хочу сделать здесь, чтобы, с пустым, возвращающий позицию в Sudoku, который пуст (Значение его элемент ничего). Так как принято начинать считать с 0, это то, что делает -1 в пустой функции. Тип (Int, Int) представляет (номер строки, номер элемента). В какой строке есть пустая ячейка, а какой из элементов в этой строке содержит пустую ячейку.

Если я запустил это с помощью «пустой» ячейки в первой строке, я получаю ожидаемый результат. Если, однако, пустая ячейка находится в другом месте, чем в первой строке, я получаю неисчерпаемую ошибку. Довольно уверен, что функция wheressNothing является причиной этого, нет базовой базы. Я просто не могу понять, как его решить. Есть идеи?

редактировать: Когда я пишу действительное решение судоку и изменяет значение во 2-й строке в настоящее время, я получаю сообщение об ошибке:

*Main> blank example2 
(0,*** Exception: Sudoku.hs:166:1-73: Non-exhaustive patterns in function whereIsNothing 

Так где функция должна возвращать первую цифру в качестве 1, он возвращает его как ноль.

+1

'whereIsNothing': Что произойдет, если список пуст? Btw, 'isNothingPresent' просто' any (== Nothing) '. – Zeta

+0

@Zeta Я попытался создать свою пустую функцию таким образом, что whereIsNothing будет вызван, только если ничего не было. Я не уверен, как обработать пустой список в качестве аргумента для этой функции. – Rewbert

+0

@ Rewbert вы можете изменить 'whereIsNothing :: Block -> Maybe Int', а затем * вытянуть * все это до конца (вы увидите, что большинство ваших функций действительно частичны - например, как« пустым »вернуть что-либо, когда нет * пусто * поле осталось?) * ~ Luke ~: Пусть типы вас ведут! * – Carsten

ответ

1

Во-первых, если вы пытаетесь решить судоку, вы можете предпочесть некоторое алгебраическое упрощение: вместо того, чтобы использовать [[Maybe Int]], вы можете использовать [[[Maybe Bool]]], представляющие цифры от 1-9 по своим возможностям (т.е. Just 8 становится `[ Просто False, просто False, просто False, просто False, просто ложно, просто ложно, просто ложно, просто правда, просто ложно]). Итак, у вас есть строки и столбцы, как и раньше, но также файлов на основе новой добавленной «глубины» для судоку. Ваши обычные правила Sudoku становятся: в каждой строке должно быть ровно одно True, ровно один True в каждом столбце, ровно один True в каждом файле и ровно один True на каждой глубине каждого «блока».

Во-вторых, все, что вы делаете, решается библиотечными функциями. В частности:

import Data.Maybe (isNothing, listToMaybe) 

allpositions :: [Pos] 
allpositions = [(x, y) | x <- [1..9], y <- [1..9]]  

getValue :: Sudoku -> Pos -> Maybe Int 
getValue s (x, y) = s !! x !! y 

blank :: Sudoku -> Maybe Pos 
blank s = listToMaybe $ filter (isNothing . getValue s) allpositions 

Здесь listToMaybe является стандартной функцией библиотеки, которая подобна head, но не ломается, когда список [] (так что вы можете поймать тот случай, когда не остались без пробелов, и вы сделали с решение Судоку!) Вы также можете просто сохранить список пустых позиций.

 Смежные вопросы

  • Нет связанных вопросов^_^