F # функцыя вяртае некалькі тыпаў (зваротны выгляд універсальнага тыпу аб'екта)?

Я працягваю навучанне F # шаблону з маёй простай функцыяй, якая павінна вяртаць квадратны корань, калі аргумент з'яўляецца лік, аргумент у адваротным выпадку. Я змяніў яго трохі, і гэта выглядае наступным чынам.

let my_sqrt (o: obj) =
  match o with
  | :? float as d -> (sqrt d).ToString()
  | _ as x -> x.ToString()

Ён працуе выдатна для маёй мэты, але што, калі я не хачу, каб кінуць вяртаецца значэнне радкі? Як я магу вярнуць "нейкі аб'ект", а затым выкарыстоўваць яго ў printfn "% A" (my_sqrt [| 1; 2; 3 |]) будаўніцтва?

0
Проста напісаў прыклад функцыі, якія вяртаюць розныя тыпы, каб паказаць, што я хачу ведаць :-)
дададзена аўтар Nik, крыніца
Проста напісаў прыклад функцыі, якія вяртаюць розныя тыпы, каб паказаць, што я хачу ведаць :-)
дададзена аўтар Nik, крыніца
Проста напісаў прыклад функцыі, якія вяртаюць розныя тыпы, каб паказаць, што я хачу ведаць :-)
дададзена аўтар Nik, крыніца
Калі я магу спытаць, якая мэта вяртання аргумент нязменным, калі гэта не паплавок? У якой сітуацыі гэта было б карысна?
дададзена аўтар sepp2k, крыніца

10 адказы

Нягледзячы на ​​тое, што ваш прыклад з'яўляецца толькі дэманстрацыя таго, што вы спрабуеце зрабіць, гэта варта адзначыць, што гэта, верагодна, не вельмі добры дызайн. У F #, вы звычайна не выкарыстоўваць функцыі, якія працуюць на аб'ектах з выкарыстаннем злепкаў - лепшы спосаб, каб прадставіць гэта было б прадузята саюз:

type MyInput = 
  | Numeric of float
  | Other of obj

let my_sqrt = function
  | Numeric d -> Numeric (sqrt d)
  | Other o -> Other o

Гэтая функцыя працуе на тыпу, які з'яўляецца альбо Лікавыя або Іншая , але дзякуючы DU, вам не патрэбныя ніякія адліўку. Я думаю, што нешта ўздоўж гэтых ліній будзе лепш падыходам да вашым рэальным праблемах таксама.

8
дададзена
Ці можаце вы растлумачыць трохі больш? Я пачатковец у F # і моцных тыпаў у цэлым, так што гэта выглядае крыху дзіўна для мяне. Вызначым выгляд набору тыпаў, вызначыць функцыю, якая працуе з яго падтыпаў, але з якой мэтай на абгортачнай вяртаюцца значэння гэтай функцыі? Каб паказаць, што функцыя атрымлівае MyInput і вяртае MyInput?
дададзена аўтар Nik, крыніца
@dig Ідэя заключаецца ў тым, што вы павінны быць дакладна пра тое, што вяртае функцыя - калі ў вас ёсць функцыя OBJ -> OBJ , вы кажаце, што ён можа ўзяць што-небудзь і нічога вяртаць. Мэта MyInput павінен сказаць, што функцыя прымае альбо паплаўка (у гэтым выпадку ён робіць нешта асаблівае) або што-небудзь яшчэ. Я загарнуў вяртаецца значэнне ў тым жа тыпе, таму што я падазраваў, што вы можаце адрозніваць два выпадкі пасля выкліку функцыі таксама.
дададзена аўтар Tomas Petricek, крыніца
@dig Але я думаю, што цяжка даць карысны адказ, не ведаючы больш аб канкрэтным выкарыстанні, што вы зацікаўлены ў.
дададзена аўтар Tomas Petricek, крыніца

Нягледзячы на ​​тое, што ваш прыклад з'яўляецца толькі дэманстрацыя таго, што вы спрабуеце зрабіць, гэта варта адзначыць, што гэта, верагодна, не вельмі добры дызайн. У F #, вы звычайна не выкарыстоўваць функцыі, якія працуюць на аб'ектах з выкарыстаннем злепкаў - лепшы спосаб, каб прадставіць гэта было б прадузята саюз:

type MyInput = 
  | Numeric of float
  | Other of obj

let my_sqrt = function
  | Numeric d -> Numeric (sqrt d)
  | Other o -> Other o

Гэтая функцыя працуе на тыпу, які з'яўляецца альбо Лікавыя або Іншая , але дзякуючы DU, вам не патрэбныя ніякія адліўку. Я думаю, што нешта ўздоўж гэтых ліній будзе лепш падыходам да вашым рэальным праблемах таксама.

8
дададзена
Ці можаце вы растлумачыць трохі больш? Я пачатковец у F # і моцных тыпаў у цэлым, так што гэта выглядае крыху дзіўна для мяне. Вызначым выгляд набору тыпаў, вызначыць функцыю, якая працуе з яго падтыпаў, але з якой мэтай на абгортачнай вяртаюцца значэння гэтай функцыі? Каб паказаць, што функцыя атрымлівае MyInput і вяртае MyInput?
дададзена аўтар Nik, крыніца
@dig Ідэя заключаецца ў тым, што вы павінны быць дакладна пра тое, што вяртае функцыя - калі ў вас ёсць функцыя OBJ -> OBJ , вы кажаце, што ён можа ўзяць што-небудзь і нічога вяртаць. Мэта MyInput павінен сказаць, што функцыя прымае альбо паплаўка (у гэтым выпадку ён робіць нешта асаблівае) або што-небудзь яшчэ. Я загарнуў вяртаецца значэнне ў тым жа тыпе, таму што я падазраваў, што вы можаце адрозніваць два выпадкі пасля выкліку функцыі таксама.
дададзена аўтар Tomas Petricek, крыніца
@dig Але я думаю, што цяжка даць карысны адказ, не ведаючы больш аб канкрэтным выкарыстанні, што вы зацікаўлены ў.
дададзена аўтар Tomas Petricek, крыніца

Нягледзячы на ​​тое, што ваш прыклад з'яўляецца толькі дэманстрацыя таго, што вы спрабуеце зрабіць, гэта варта адзначыць, што гэта, верагодна, не вельмі добры дызайн. У F #, вы звычайна не выкарыстоўваць функцыі, якія працуюць на аб'ектах з выкарыстаннем злепкаў - лепшы спосаб, каб прадставіць гэта было б прадузята саюз:

type MyInput = 
  | Numeric of float
  | Other of obj

let my_sqrt = function
  | Numeric d -> Numeric (sqrt d)
  | Other o -> Other o

Гэтая функцыя працуе на тыпу, які з'яўляецца альбо Лікавыя або Іншая , але дзякуючы DU, вам не патрэбныя ніякія адліўку. Я думаю, што нешта ўздоўж гэтых ліній будзе лепш падыходам да вашым рэальным праблемах таксама.

8
дададзена
Ці можаце вы растлумачыць трохі больш? Я пачатковец у F # і моцных тыпаў у цэлым, так што гэта выглядае крыху дзіўна для мяне. Вызначым выгляд набору тыпаў, вызначыць функцыю, якая працуе з яго падтыпаў, але з якой мэтай на абгортачнай вяртаюцца значэння гэтай функцыі? Каб паказаць, што функцыя атрымлівае MyInput і вяртае MyInput?
дададзена аўтар Nik, крыніца
@dig Ідэя заключаецца ў тым, што вы павінны быць дакладна пра тое, што вяртае функцыя - калі ў вас ёсць функцыя OBJ -> OBJ , вы кажаце, што ён можа ўзяць што-небудзь і нічога вяртаць. Мэта MyInput павінен сказаць, што функцыя прымае альбо паплаўка (у гэтым выпадку ён робіць нешта асаблівае) або што-небудзь яшчэ. Я загарнуў вяртаецца значэнне ў тым жа тыпе, таму што я падазраваў, што вы можаце адрозніваць два выпадкі пасля выкліку функцыі таксама.
дададзена аўтар Tomas Petricek, крыніца
@dig Але я думаю, што цяжка даць карысны адказ, не ведаючы больш аб канкрэтным выкарыстанні, што вы зацікаўлены ў.
дададзена аўтар Tomas Petricek, крыніца

Я думаю, што вы хочаце

let my_sqrt (o: obj) =
  match o with
  | :? float as d -> (sqrt d) :> obj
  | _ as x -> x

толькі вентыляцыйны аб'екта

5
дададзена

Я думаю, што вы хочаце

let my_sqrt (o: obj) =
  match o with
  | :? float as d -> (sqrt d) :> obj
  | _ as x -> x

толькі вентыляцыйны аб'екта

5
дададзена

Як ужо згадвалася ў TP адказ, агульная ідэя павінна быць, па магчымасці, размяшчаць інфармацыю ў вашай сістэме тыпу.

  • Тады <�моцны> прасцей для вас чытаць і разважаць вашу праграму, так як у вас ёсць <�моцны> назва рэчы.

  • Гэта азначае, што F # можа на самай справе <�моцны> Праца для вас і сказаць вам, калі вы зрабілі нешта няправільна

Гэта робіць яго заўсёды варта інвестыцый.

0
дададзена

Я згодны з Томасам, які з дапамогай размечаную Саюза было б лепш. Там няма альбо манадай, убудаваных у F #, але вы можаце выкарыстоўваць Выбар саюз, каб стандартызаваць інтэрфейс:

let my_sqrt (o : obj) = 
  match o with 
  | :? float as d -> Choice1Of2 (sqrt d) 
  | o -> Choice2Of2 o;;
0
дададзена

Я думаю, што ваша функцыя нармальна. Калі вы хочаце, каб вылічыць кожны квадратны корань, вы павінны супаставіць функцыі над масівам, як гэта:

Array.map my_sqrt [| 1.0; 2.0; 3.0 |] |> printfn "%A"
0
дададзена

Я думаю, што ваша функцыя нармальна. Калі вы хочаце, каб вылічыць кожны квадратны корань, вы павінны супаставіць функцыі над масівам, як гэта:

Array.map my_sqrt [| 1.0; 2.0; 3.0 |] |> printfn "%A"
0
дададзена

Я думаю, што ваша функцыя нармальна. Калі вы хочаце, каб вылічыць кожны квадратны корань, вы павінны супаставіць функцыі над масівам, як гэта:

Array.map my_sqrt [| 1.0; 2.0; 3.0 |] |> printfn "%A"
0
дададзена