Обо мне

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

понедельник, 19 апреля 2010 г.

F# - красивая конструкция

Сижу, пишу сервер. Есть у меня две функции, которые принимают данные разных типов (String и byte array) и отправляют их в поток - первая, соответственно, для отправки клиенту текста (заголовки всякие, прочая белиберда), вторая - для отправки изображений и прочей бинарщины.

И вот, благодаря паттерн матчингу, их можно объединить:

let sendToStream (str: NetworkStream) (bin: Object) =
    match bin with
        | :? string as strn ->
            str.Write(System.Text.Encoding.UTF8.GetBytes(strn), 0, strn.Length)
        | :? (byte[])  as bytarr ->
            str.Write(bytarr, 0, bytarr.Length)

Вот такая вот функция. Что радует - увеличившийся уровень абстракции - стоит появиться какому-нибудь новому типу, для которого нужен свой способ отправки - все, что нужно изменить - паттерн. Благодаря наличию Object на верхнем уровне мы можем совать какие угодно данные в функцию. Правда, тут стоит следить за наследованием - ведь проверка типов может не дойти до нашего "нового" типа. Поэтому наиболее частные типы следует размещать как можно раньше.

P.S. Кстати, в приведенном примере компилятор найдет изъян - не покрыты все паттерны. Дело лечится добавлением граничного случая | _ -> failwith "Invalid input" например.

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

  1. Могу обобщить: в большинстве языков семейства ML (SML, OCaml, F#) сравнение с образцом вообще на высоте.

    Только Haskell подкачал - у него pattern matching неисчерпывающий (non-exhaustive), то-есть в твоем случае предупреждения от компилятора о непокрытых паттернах ты-б не дождался.

    ОтветитьУдалить
  2. Duck typing какой-то. В F# и прочих ML есть более правильный для этого механизм, который точно так же будет применим и здесь, но при этом будет сохранять строгую типизацию.
    Чем вам discriminated union не гож?
    type Data = StringData of string | BinaryData of byte[]

    И паттерн матчинг без приведения типов сработает, и добавление новых типов данных не так уж сложно, да и за наследованием следить не надо.

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