Обо мне

Моя фотография
Дикий Полярный Сов

суббота, 27 марта 2010 г.

F# Mono Bug, или Микрософт как всегда.

Наткнулся сегодня на интересный баг в F#.
До конца локализовать пока не удалось, но, кажется, что паттерн матчинг с 'a option неправильно работает.
Итак. Имеем код (да, это тот самый шифр цезаря :] ):


module Caesar

let alphabet = Array.ofSeq "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.,?!+=/"

let getIndex (arr: 'a[]) (elt: 'a) =
    let optIndex = arr |> Array.tryFindIndex( (=) elt )
    match optIndex with
    | Some(x) ->
        printfn "found %A" x
        x
    | None ->
        printfn "None"
        -1

let encodeLetter (shift: int) (letter: char) =
    let idx =
        letter
        |> getIndex alphabet
    printfn "%c - %d" letter idx
    alphabet.[
        ( idx + shift ) % (Array.length alphabet)
        ]


В винде все работает, как и предполагалось - написав в fsi, к примеру

#load "caesar.fs"
Caesar.encodeLetter 5 'a';;

Получим на экране

found 0
a - 0
val it : char = 'f'

То есть - getIndex отработал как надо, достал нам индекс, что, в свою очередь означает, что паттерн матчинг Some(x) сработал. Под моно же имеем следующую картину:

None
a - -1
val it : char = 'e'

То есть явно видно, что в том же самом коде тот же самый паттерн не сработал.

Бьюсь в истерике Очень интересный баг.


UPD: Однако, если вызывать getIndex напрямую - выводит все как полагается. Значит, беспорядки начинаются уже в encodeLetter - почему-то "теряется"... пока не пойму что.

UPD2: Причина, оказывается, крылась в генерализации функции (я явно указал 'a в качестве типа параметра). Как только поменял типы параметров в getIndex на char - заработало и под Mono. Подозреваю, тут что-то связано с выводом типов. Буду ковырять дальше.

UPD3: У Mono с выводом типов вообще как-то не очень ладится. Не могли сделать все как в дотнет.

2 комментария:

  1. >> "У Mono с выводом типов вообще как-то не очень ладится. Не могли сделать все как в дотнет."

    Пардон, а причём тут Mono? Механизм вывода типов вроде как внутри компилятора, а компилятор написан Microsoft, разве нет?

    ОтветитьУдалить
  2. Вообще, последний постскриптум больше саркастический, нежели информативный. Баг тестировал под виндой и под моно. Под виндой замечен не был. Поэтому и решил, что причина в моно

    ОтветитьУдалить