F # нарисовать геометрический объект - PullRequest
0 голосов
/ 02 декабря 2018

Мне нужно создать 3 функции.Тот, который рисует прямоугольник, другой - треугольник, а последний - дом, как на рисунке ниже.

type RoboInstruction = | F | L | R

type RoboProgram =
    | Forward
    | Left
    | Right
    | Seq of RoboProgram * RoboProgram
    | Repeat of Nat * RoboProgram

let rectangle: RoboProgram = (....)
let triangle: RoboProgram = (....)
let nikolaus: RoboProgram = (....)

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

let rectangle: RoboProgram =
  Repeat(2,
    Repeat(3N, Forward);
    Repeat(90N, Left);
    Repeat(2N, Forward);
    Repeat(90N, Left))

1 Ответ

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

Поскольку в команде Seq используются кортежи, которые позволяют объединять только две команды за раз, вам потребуется вложить несколько Seq с, чтобы можно было объединить 4 инструкции.

(я переключился сNat до int только потому, что Nat требует от меня загрузки дополнительной библиотеки.)

Вы можете сделать это так:

let rectangle: RoboProgram =
    Repeat(2,
        Seq(
            Seq(Repeat( 3, Forward)
              , Repeat(90, Left   ))
          , Seq(Repeat( 2, Forward)
              , Repeat(90, Left   ))
        )
    )

Или вот так:

let rectangle: RoboProgram =
    Repeat(2,
        Seq(Repeat( 3, Forward)
      , Seq(Repeat(90, Left   )
      , Seq(Repeat( 2, Forward)
      ,     Repeat(90, Left   )
        )))
    )

Этот второй стиль типичен для функций связывания из функционального программирования.Фактически в F # вы могли бы создать Вычислительное выражение, чтобы сделать это:

type RoboBuilder() = // Computation Expression builder
    member __.ReturnFrom x = x
    member __.Bind(x, f) = Seq(x, f x)

let robo = RoboBuilder()

, который позволил бы вам сгенерировать тот же самый код, подобный этому:

let rectangle3 =
    Repeat(2, robo {
        let! _ = Repeat( 3, Forward)
        let! _ = Repeat(90, Left   )
        let! _ = Repeat( 2, Forward)
        return!  Repeat(90, Left   )
    })

Если эта последняя часть не яснане волнуйтесь, это расширенная функция F #.

...