Рекомендации по стилю для глобальных переменных в F # - PullRequest
6 голосов
/ 18 мая 2011

Для проекта, над которым я работаю, мне нужна глобальная переменная (технически это не так, я могу построить ее, а затем передать ее каждому вызову функции и сообщить об этом каждому вызову функции, но это кажется простокак хакерский, менее читаемый и более трудоемкий.)

Глобальные переменные - это таблицы поиска (финал, открытие книги и транспонирование / кэш) для игры.

Тот факт, что часть кодаможет потерять часть своего бессильного поведения, это на самом деле смысл (ускорения), да, я знаю, что глобальное изменяемое состояние - это плохо, в этом случае оно действительно стоит (10x + улучшение производительности)

Так вот вопрос "создать синглтон или использовать статическое значение в статическом классе с комбинаторами "

Они фактически идентичны, но мне любопытно, что люди уже делали раньше для решения такого рода проблем

Или, альтернативно, должен ли япередать это всем (или, по крайней мере, ссылку на него), это действительно лучший ответ?

Ответы [ 3 ]

4 голосов
/ 18 мая 2011

Вот решение, похожее на решение, опубликованное @Yin Zhu's, но с использованием абстрактных типов для указания интерфейса использования для изменяемого значения, локального определения для его инкапсуляции и литералов объекта для обеспечения реализации (взято из ExpertF # - в соавторстве с Доном Саймом):

type IPeekPoke =
    abstract member Peek: unit -> int
    abstract member Poke: int -> unit

let makeCounter initialState =
    let state = ref initialState
    { new IPeekPoke with
        member x.Poke(n) = state := !state + n
        member x.Peek() = !state }
3 голосов
/ 19 января 2013

Вы также можете сделать это со статическими полями, например:

type Common() = 

    static let mutable queue : CloudQueue = null
    static let mutable storageAccount : CloudStorageAccount = null

    static member Queue 
        with get() = queue
        and set v = queue <- v
    static member StorageAccount 
        with get() = storageAccount
        and set v = storageAccount <- v

В другом модуле просто:

open Common
Common.Queue <- xxxx
2 голосов
/ 18 мая 2011

вот соглашение, используемое в библиотеке F # PowerPack Matrix (\src\FSharp.PowerPackmath\associations.fs):

// put global variable in a special module
module GlobalAssociations =
    // global variable ht
    let ht = 
        let ht = new System.Collections.Generic.Dictionary<Type,obj>() 
        let optab =
            [ typeof<float>,   (Some(FloatNumerics    :> INumeric<float>) :> obj);
              typeof<int32>,   (Some(Int32Numerics    :> INumeric<int32>) :> obj);
                  ...
              typeof<bignum>,  (Some(BigRationalNumerics   :> INumeric<bignum>) :> obj); ]

        List.iter (fun (ty,ops) -> ht.Add(ty,ops)) optab;
        ht

    // method to update ht
    let Put (ty: System.Type, d : obj)  =
        // lock it before changing
        lock ht (fun () -> 
            if ht.ContainsKey(ty) then invalidArg "ty" ("the type "+ty.Name+" already has a registered numeric association");
            ht.Add(ty, d))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...