2014-10-09 7 views
0

Rellevant 유형 : 나는리스트의 목록을 가지고얻기 위치

Data Sudoku = Sudoku [[Maybe Int]] 
type Block = [Maybe Int] 
rows :: Sudoku -> [[Maybe Int]] 
rows (Sudoku rs) = rs 

, [[아마 지능], 그리고 난

type Block = [Maybe Int] 

내가 할당

을 언급 한 작업은 스도쿠 해법을 만드는 것이므로 아무것도없는 빈 셀의 위치를 ​​반환하는 함수가 필요합니다. 내가 구 개 목록, 각 포함하는 구 개 요소, 아무것도 또는 그냥 지능까지 스도쿠의 실제 레이아웃

Sudoku [ 
     , list1 
     , list2 
     .... ] 

될 것이다.

type Pos = (Int, Int) 

첫 번째 Int 인 포지션은 빈 셀이 포함 된 '행'을 나타내야합니다. 두 번째 요소는 행이 빈 요소 인 요소를 나타냅니다. 난 내가 이러한 기능을 결합하고 스도쿠를 검사하는 함수의 빈을 생성하고 빈 셀의 위치를 ​​반환해야 이제

whichRow :: Sudoku -> Int 
whichRow (Sudoku (x:xs)) = 
    if isNothingPresent x == False then 1 + whichRow (Sudoku xs) else 1 

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

isNothingPresent :: Block -> Bool 
isNothingPresent b 
    | Nothing `notElem` b = False 
    | otherwise   = True 

를 작성했습니다. 나는 놀고 시도했다 :

blank :: Sudoku -> Pos 
blank sud = do k <- (whichRow sud) 
       n <- (whereIsNothing (head (drop (k-1) (rows sud)))) 
       (return (k, n)) 

분명히 틀린 나는 유형과 모든 종류의 물건을 얻는다. 그리고 그곳에도 블록이있는 것처럼 보입니다. 누구든지 올바른 방향으로 나를 가리킬 수 있을까요? 감사!

나는 이러한 오류를 얻을 :

Sudoku.hs:159:22: 
    Couldn't match expected type `(Int, Int)' with actual type `Int' 
    In a stmt of a 'do' block: k <- (whichRow sud) 
    In the expression: 
     do { k <- (whichRow sud); 
      n <- (whereIsNothing (head (drop (k - 1) (rows sud)))); 
      (return (k, n)) } 

Sudoku.hs:160:22: 
    Couldn't match expected type `(Int, t0)' with actual type `Int' 
    In a stmt of a 'do' block: 
     n <- (whereIsNothing (head (drop (k - 1) (rows sud)))) 
    In the expression: 
     do { k <- (whichRow sud); 
      n <- (whereIsNothing (head (drop (k - 1) (rows sud)))); 
      (return (k, n)) } 

Sudoku.hs:161:24: 
    Couldn't match expected type `Int' with actual type `(Int, t0)' 
    Relevant bindings include n :: t0 (bound at Sudoku.hs:160:16) 
    In the first argument of `return', namely `(k, n)' 
    In a stmt of a 'do' block: (return (k, n)) 
    In the expression: 
     do { k <- (whichRow sud); 
      n <- (whereIsNothing (head (drop (k - 1) (rows sud)))); 
      (return (k, n)) } 

편집 다시 : 또한 내가 더 빈 셀이없는 경우이 기능이 재미 작동합니다 확신합니다 ..

+0

,

isNothingPresent :: Block -> Bool isNothingPresent b = not $ Nothing 'notElem' b 

하거나

isNothingPresent :: Block -> Bool isNothingPresent b | Nothing 'notElem' b = False | otherwise = True 

우리가 그것을 다시 수를 살펴 보자. 왜 분명히 잘못 되었습니까? 어떤 유형의 오류가 발생합니까? – bheklilr

+0

오류가있는 게시물이 업데이트되었습니다! – Rewbert

답변

3

먼저이 꼬리 재귀 사용 재귀 함수는 아닙니다. 둘째

whichRow :: Sudoku -> Int 
whichRow s = whichRow' s 0 -- tail-recursive 
    where 
    whichRow' (Sudoku (x:xs)) i = if isNothingPresent x 
     then 1 
     else whichRow' (Sudoku xs) (i+1) 

, 패턴 매칭에 모든 경우에서 볼 잊지 마세요 :

whichRow :: Sudoku -> Int 
whichRow s = whichRow' s 0 
    where 
    whichRow' (Sudoku [])  i = i  -- missing case 
    whichRow' (Sudoku (x:xs)) i = if isNothingPresent x 
     then 1 
     else whichRow' (Sudoku xs) (i+1) 

셋째을, 왜 이렇게 많은 괄호를 사용합니까? 주요

blank :: Sudoku -> Pos 
blank sud = do k <- whichRow sud 
       n <- whereIsNothing (head (drop (k-1) (rows sud))) 
       return (k, n) 

그러나 -이 코드가 유효하지 않습니다. do은 모나드이지만 Int 만 사용합니다. 대신 if smth then ... 쓰기, let 대신

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

또는

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

넷째whereif smth == True then ....처럼 Bool 많이 재사용하지 않습니다 사용합니다.좀 더 간단하게 "내가 유형 오류 및 물건의 모든 종류를 얻을 분명히 잘못"

isNothingPresent :: Block -> Bool 
isNothingPresent b = Nothing `elem` b 
+0

감사합니다. 잘 쓰여진 의견입니다! 교육학, 많이 배웠어. :) – Rewbert

+0

... 그리고''$ not'notElem'b == a elem'b''. –

+0

@WillNess 확인해 주셔서 감사합니다. 처음에는'Nothing 'elem'b'라고 적었습니다.)) – viorior