2016-07-22 2 views
1

При создании змеи в консольном приложении F # я использовал следующий код для обновления окна консоли.F # метод рекурсивного сопоставления шаблонов переопределяет аргумент

//Sets the next character in accumulator 
//(i, j) are the coordinates of the game 
//(px, py) are the coordinates of snake's head 
let rec setConsoleChar acc i j px py = 
    if i=px && j=py then 
     setConsoleChar (acc+"H") (i+1) j px py 
    else 
     match i, j with 
     | ... 

Но я не мог не задаться вопросом, является ли сравнение (px, py) может быть в согласующего шаблон блока, а также. Я попытался использовать следующий код, однако при попадании указатели (i, j) изменились, указав на (px, py), что привело к ошибочному возвращаемому значению, содержащему ничего, кроме «H».

match i, j with 
| px, py -> setConsoleChar (acc+"H") (i+1) j px py 
| ... 

PS: если кто-нибудь знает способ упростить вещи, пожалуйста долю.

+0

Ну, ничего страшного в вашей первой версии. В вашем втором случае вы будете сопоставлять anyting 'i, j' с' px, py', потому что вы просто соответствуете любому кортежу. Вам нужно поставить на охрану или использовать активный шаблон. См. [Variable Pattern] (https://msdn.microsoft.com/visualfsharpdocs/conceptual/pattern-matching-%5bfsharp%5d/) – s952163

+2

Существует так много дубликатов - вам нужно использовать что-то вроде '| i, j, когда i = px && j = py' –

+2

Вот несколько дубликатов: http: //stackoverflow.com/questions/17272899/f-odd-pattern-matching-issues http://stackoverflow.com/questions/18649541/how -do-я-сравнить-х-и-у-в-е –

ответ

0

px и py внутри матча не указаны в аргументе.
Они согласованный i и j и рх и ру только имя, которое вы выбираете, чтобы дать им (затенение оригинальный точек и Py)

И следствие это я и J, замаскированный в рх и ру вы раздай рекурсивный вызов вместо «реальных» px и py.

0

Есть несколько комментариев и ответ, который вы должны принять во внимание. Тем не менее, когда условия сложны, и вы в конечном итоге используете много, когда охранники, может быть неплохо заглянуть в active patterns. Ниже приведен пример, который учитывает проверку равенства. Преимущество этого заключается в том, что код становится более читаемым (обычно).

let (|MATCH|NOMATCH|) (i,j,px,py) = 
     if i = px && j = py then MATCH 
     else 
      NOMATCH 

let setConsoleChar (i,j,px,py) = 
     match (i,j,px,py) with 
     | MATCH -> printfn "%A %A %A %A" (i+1) j px py 
     | NOMATCH -> printfn "%A" "Wot???" 


setConsoleChar (1,2,3, 4) 
setConsoleChar (1, 0, 1, 0) 

"Знают ???" val it: unit =()
2 0 1 0 val it: unit =()

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

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