внутреннее представление не скрыто в модуле f#

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

Все в моем коде работает просто отлично, но я не совсем доволен этим неудобством: в моем файле .fs (где я определяю тип и все мои функции) я объявил

type Picture = P of (Set<((float*float)*(float*float))> * (int*int))

Наборы описывают точки сегментов на изображении (линии), а пара int необходима для определения ограничивающего прямоугольника, в котором будет отображаться изображение (ширина и высота).

Когда я пробую свою функцию (в другом файле), я использую свою функцию сетки

let rec setBuilder (ls:((int*int)*(int*int)) list) = 
match ls with
| [] ->  Set.empty
| ((x,y),(w,z))::xs -> setBuilder xs |> Set.add ((float x,float y),(float w, float z)) 

let grid ls (wdt,hgt) = P (setBuilder ls, (wdt, hgt)) 

При этом я беру список пар / пар и создаю свою картинку

Проблема в том, что когда я создаю изображение с сеткой (в другом файле, где я пробую все свои функции), видно внутреннее представление

let persn = [((4, 0),(6, 7));  ((6, 7), (6, 10));  ((6, 10), (0, 10));  ((0, 10), (0, 12));   ((0, 12), (6, 12));   ((6, 12), (6, 14));   ((6, 14), (4, 16));   ((4, 16), (4, 18));   ((4, 18), (6, 20));  ((6, 20), (8, 20));
        ((8, 20), (10,18));   ((10, 18), (10, 16));   ((10, 16), (8, 14));   ((8, 14), (8, 12));   ((8, 12), (10, 12));   ((10, 12), (10, 14));   ((10, 14), (12, 14));   ((12, 14), (12, 10));   ((12, 10), (8, 10));   ((8, 10), (8, 8));
        ((8, 8), (10, 0));   ((10, 0), (8, 0));   ((8, 0), (7, 4));   ((7, 4), (6, 0));   ((6, 0), (4, 0))]

let box = (15,20)

let person = grid persn box

когда я интерпретирую последнюю строку, которую я получаю из консоли

val person : Picture =
P (set
[((0.0, 10.0), (0.0, 12.0)); ((0.0, 12.0), (6.0, 12.0));
((4.0, 0.0), (6.0, 7.0)); ((4.0, 16.0), (4.0, 18.0));
((4.0, 18.0), (6.0, 20.0)); ((6.0, 0.0), (4.0, 0.0));
((6.0, 7.0), (6.0, 10.0)); ((6.0, 10.0), (0.0, 10.0));
((6.0, 12.0), (6.0, 14.0)); ...], (15, 20))

есть способ скрыть эту информацию, я поискал и решение похоже на помеченное значение (но я их уже использую)

* ИЗМЕНИТЬ *

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

type Picture with
 static member(*)  (c:float,pic:Picture) =
        match pic with 
        | P(set,(wdt,hgt)) ->  P (Set.map (fun ((x,y),(w,z)) -> ((x*c,y*c),(w*c,z*c))) set, (int (round (float wdt * c)) ,int (round (float hgt * c))))   


 static member(|>>)  (pic1:Picture,pic2:Picture) =
        match pic1,pic2 with
         (P (set1,(w1,h1)), P (set2,(w2,h2))) ->   let new_p2 = (((float h1/ float h2)) * pic2) 
                                                   match new_p2 with 
                                                   P (nset2,(nw2,nh2)) -> P(Set.union set1 (Set.map (fun ((x,y),(w,z)) -> ((x + (float w1) ,y),(w + (float w1), z)) ) nset2),(w1 + nw2, h1)) 


 static member(|^^)  (pic1:Picture,pic2:Picture) =
        match pic1,pic2 with
        (P (set1,(w1,h1)), P (set2,(w2,h2))) ->  let new_pic2 = (((float  w1/ float w2)) * pic2)
                                                 match new_pic2 with
                                                 P (nset2,(nw2,nh2)) -> P(Set.union set1 (Set.map (fun ((x,y),(w,z)) -> ((x,(float h1) + y),(w,(float h1) + z)) ) nset2),(w1 , h1 + nh2))

 static member (>||>) (n, pic:Picture) =
        match n with
        | 0 ->  pic
        | m ->  pic |>> ((m-1) >||> pic)


 static member (^||^) (n, pic:Picture) =
      match n with
      | 0 -> pic
      | m -> pic |^^ ((m-1) ^||^ pic) 

person OriginalUsername    schedule 29.10.2018    source источник
comment
В функциональном программировании внутреннее представление данных обычно не скрывается. Почему ты хочешь это скрыть? Это чисто для удобства при использовании FSI или из-за того, как вы хотите структурировать свою программу?   -  person TheQuickBrownFox    schedule 29.10.2018
comment
Если вы предпочитаете, чтобы FSI не показывал значение последнего выражения, вы всегда можете добавить после него другое выражение, например (). Существует также опция --quiet при вызове fsi.exe, которая подавляет весь вывод, кроме того, что вы явно распечатываете.   -  person AMieres    schedule 29.10.2018
comment
Я хочу, чтобы тип был скрыт, потому что это запрос упражнения   -  person OriginalUsername    schedule 29.10.2018
comment
Что заставляет вас думать, что это не скрыто?   -  person Fyodor Soikin    schedule 29.10.2018
comment
Я знаю, что это показано, потому что, когда я пытаюсь использовать свою функцию в отдельном файле (в этом случае я пользователь, который не должен знать, как мне удалось реализовать мой файл .fsi) и создать изображение с моей функцией сетки, в консоли переводчика мне показывает, что P это пара (set + (int, int))   -  person OriginalUsername    schedule 29.10.2018


Ответы (1)


Просто напишите type Picture = private P of ..., тогда другие модули не смогут видеть внутреннюю часть Picture.

Примечание: если вы пишете type private Picture = P of ..., это означает, что другие модули не могут видеть тип Picture.

person Nghia Bui    schedule 29.10.2018
comment
Хм, странно. Пожалуйста, проверьте мой демонстрационный код здесь. Если присутствует ключевое слово private, у нас ошибка компилятора, потому что мы пытаемся получить доступ к внутренней части типа из других модулей. Удалив ключевое слово, ошибка исчезнет. Может быть, ваша версия F# слишком старая? - person Nghia Bui; 06.11.2018
comment
я попробую, как только смогу, ты Yhea, это может быть версия, вчера я обновил monodevelop, но до этого я запускал версию, загруженную в марте этого года. - person OriginalUsername; 06.11.2018