2014-09-29 3 views
6

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

let combinePath (path : string) (fileName : string) = ... 

Мне кажется, что типы фантомные будет хороший способ, чтобы поймать любые окна смешивания. Но я не понимаю, как применить этот пример только в F# phantom types question.

Как бы реализовать в этом примере фантомные типы? Как я могу назвать combPath? Или я пропустил более простое решение проблемы?

ответ

12

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

type Path = Path of string 
type Fname = Fname of string 
let combinePath (Path(p)) (Fname(file)) = System.IO.Path.Combine(p, file) 

Вы могли бы назвать это таким образом

combinePath (Path(@"C:\temp")) (Fname("temp.txt")) 
+5

Так как те один-случай Дус, вы также можете сделать 'пусть combinePath (Путь (р)) (Fname (е)) = ...', конец -result будет одинаковым :) –

+0

Да. Это будет проще. Обновленный пост, спасибо! – Petr

+0

Это означает объявление типа для каждого типа параметра. Думаю, я думал, что это может быть своего рода единица измерения, строка строка . Хотя для этого все равно нужны типы для Path и FileName, поэтому в конце концов все равно ... отвечая на мой вопрос, я думаю. –

7

Я согласен с взятием Petr, но для полноты картины, обратите внимание, что вы можете только используйте типы фантомов, когда у вас есть общий тип, чтобы использовать их, чтобы вы ничего не могли сделать с помощью простых входов string. Вместо этого вы могли бы сделать что-то вроде этого:

type safeString<'a> = { value : string } 

type Path = class end 
type FileName = class end 

let combinePath (path:safeString<Path>) (filename:safeString<FileName>) = ... 

let myPath : safeString<Path> = { value = "C:\\SomeDir\\" } 
let myFile : safeString<FileName> = { value = "MyDocument.txt" } 

// works 
let combined = combinePath myPath myFile 

// compile-time failure 
let combined' = combinePath myFile myPath 
+0

Очевидно, что дискриминационный союз - лучший способ сделать это. Типы фантомов кажутся избыточными для F #. Наверное, поэтому не так много внимания. –

+0

@FsharpPete - Я не думаю, что это совершенно правильно; в этом конкретном сценарии DU могут быть лучше, но есть, конечно, сценарии, в которых пригодны типы фантомов (и я не думаю, что F # заметно отличается от большинства других языков с точки зрения использования одного метода или другого). – kvb

+0

Да, я вижу это сейчас. При подходе фантомных типов вы можете указать тип фантома вне модуля/пакета, а не с дискриминационным объединением. –

Смежные вопросы