Обмен переменных при сопоставлении с образцом? - PullRequest
0 голосов
/ 22 ноября 2018

Предположим, у вас есть 2 целочисленные переменные a и b. Как бы вы поменяли их местами, только если a> b с помощью выражения соответствия?Если a <= b, не меняйте местами. </p>

На императивном языке:

if (a > b){
   int temp=a;
   a=b;
   b=temp;
}

Выполнение того же в ocaml кажется удивительно трудным.

Я пытался

let swap a b = 
 match a,b with 
  | a,b when a > b -> b,a
  | a,b when a <= b -> a,b

Я пытаюсь это сделать, потому что в следующем вызове функции я хочу убедиться, что x больше двух переменных.

Ответы [ 3 ]

0 голосов
/ 22 ноября 2018

Без состояния вы не можете «поменять» значения переменных, так как переменные являются неизменяемыми.Лучше всего использовать кортеж и вводить новые переменные в область видимости.Пример:

let diff a b =
    let (min, max) = if a <= b then (a, b) else (b, a)
    in max - min

Конечно, вы можете использовать те же идентификаторы и скрывать исходные переменные:

let diff a b =
    let (a, b) = if a <= b then (a, b) else (b, a)
    in b - a

Хотя это не очень помогает с читабельностью.

0 голосов
/ 01 декабря 2018

Просто для справки, если вы хотите поменять местами значения в двух ссылках, это будет выглядеть следующим образом:

let swap a_ref b_ref =
  let a, b = !a_ref, !b_ref in
  a_ref := b;
  b_ref := a
;;

, который имеет тип val swap : 'a ref -> 'a ref -> unit.

0 голосов
/ 22 ноября 2018

Один простой способ:

 let swap a b = 
     if (a>b) then (b,a) 
     else (a,b)

Но это не эквивалентно коду C, ваш код C меняет значение переменной - так поступает императивный язык.

В Ocaml нет побочных эффектов (кроме случаев, когда вы используете ссылку на какой-то int).Эта swap функция вернет кортеж, члены которого всегда упорядочены (первый член всегда будет меньше второго порядка).

...