2016-09-06 2 views
2
type FFRec<'state when 'state: (member Tape: Stack<unit -> unit>) 
        and 'state: (member Mem: ObjectPool) 
        and 'state: (member Str: CudaStream) 
        and 'state: (member Workspace: Workspace) 
        and 'state: (member IsInferenceOnly: bool)> = 
    { 
    W: d2M 
    b: d2M 
    a: d2M -> 'state -> d2M * 'state 
    } 

Можно заменить все эти ограничения члены с интерфейсом, но небольшая проблема с этим подходом является то, что компилятор не достаточно умен, чтобы понять, что если у меня есть функция, как это, например:Можно ли сделать сокращения типов с ограничениями членов?

let inline reluInitializer (state: ^state) (a: ^a) = 
    let scale = (1.0f/sqrt(addDims a |> float32)) 
    fillRandomUniformMatrix((str state),a,scale,0.0f) 
    a 

Он не поймет, что ^state должен будет иметь ограничение интерфейса и дать мне необъяснимую подпись и реализацию, отличающиеся ошибкой в ​​объявлении общих параметров записи.

Если это вообще возможно, я бы предпочел использовать ограничения членов, чем явные интерфейсы, но я не мог найти способ использовать сокращения типов, чтобы сократить указанные выше ограничения. Возможно ли это в текущем F #?

+0

Посмотрите ключевое слово 'inline'. Это лучшее приближение F # для того, что вы пытаетесь сделать. – asibahi

ответ

4

Нет, нельзя использовать статически разрешенные параметры типа с типами.

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

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

Что касается проблемы, которую вы описываете с помощью параметра ^state в вашем примере, я не совсем понимаю, что это такое: ваша функция не имеет доступа к члену в нем, поэтому я не вижу, как это может вызвать ошибка, связанная с членами.


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

+0

Если функция accessor вы имеете в виду тип встроенной функции, такой как 'let inline dispose v = (^ b: (member Dispose: unit -> unit) v)', то я использую их повсюду. То, что я показал выше, - это лишь небольшая часть моей 2-местной библиотеки LOC, поэтому я не был уверен, нужно ли показывать реализацию. В отличие от обычных функций let, компилятор требует, чтобы я явно выделял ограничения членов в классах и записях, а не сам выводил их, поэтому я действительно спрашивал, можно ли сокращать ограничения типа. –

+0

Прямо сейчас я пытаюсь сделать это с помощью наследования и получаю действительно бесполезные ошибки типа при использовании ограничений наследования. В принципе, вся библиотека встроена и для краткости использует статически разрешенные параметры типа. –

+1

У вас не возникли проблемы с вашим вопросом или проблемой. Попробуйте быть более конкретным. Попробуйте предоставить примеры вместе с желаемыми результатами и сообщениями об ошибках, которые вы получите. –