Programim dhe zhvillim, javascript, python, php, html

Funksioni ocaml më kërkon të kthej njësinë në vend të "një listë".

Kohët e fundit kam filluar të kodoj në ocaml dhe kjo gjuhë programimi është e ndjeshme kur bëhet fjalë për përcaktimin e asaj që dua të kthejë një funksion. Dua të shkruaj një funksion që përdor 2 lista si parametra (që supozohet të jenë në rend rritës dhe me elementë të tipit int) dhe kthen një listë që përmban të gjithë elementët e 2 listave të para, gjithashtu në rend rritës.

Ja çfarë kam arritur të arrij deri tani:

let inter l1 l2 =
let rec aux l1 l2 l3=
if List.hd l1<List.hd l2 then aux (List.tl l1) l2 (List.hd l1 :: l3)
else (if List.hd l1>List.hd l2 then aux l1 (List.tl l2) (List.hd l2::l3)
      else (if l1 = [] then List.fold_left (fun x y -> y::x) l3 l2
            else if l2=[] then List.fold_left (fun x y -> y::x) l3 l1
     ))
  in List.rev (aux l1 l2 []);;

Por kur e përpiloj, më kthen këtë mesazh gabimi:

Error: This expression has type 'a list
       but an expression was expected of type unit

Kur telefonoj funksionin, funksionon mirë, por funksionon ashtu siç pritej, por ajo që më shqetëson është mesazhi i gabimit. Ndonjë ide pse shfaqet?

PS: Unë përdor Emacs - Tuareg Mode si një redaktues teksti dhe përpilues.

14.10.2016

Përgjigjet:


1

Konstrukti sintaksor if/else është një shprehje. Lloji i të gjithë shprehjes përcaktohet nga lloji i shprehjeve të kthyera nga degët. Natyrisht, ato duhet të jenë të të njëjtit lloj. Nëse nuk e keni specifikuar degën else, atëherë supozohet se dega e lënë jashtë është një shprehje e tipit unit, në thelb if c then e është një stenografi për if c then e else ().

Shprehja:

 if l2=[] then List.fold_left (fun x y -> y::x) l3 l1

është në fakt një stenografi për:

 if l2=[] then List.fold_left (fun x y -> y::x) l3 l1 else ()

Kështu që OCaml përpiqet të unifikojë List.fold_left (fun x y -> y::x) l3 l1 me (). Sigurisht që ato kanë lloje të ndryshme. Nëse shtoni një degë të qartë else, atëherë gjithçka do të kontrollohet (nuk jam i sigurt për korrektësinë):

let inter l1 l2 =
let rec aux l1 l2 l3=
if List.hd l1<List.hd l2 then aux (List.tl l1) l2 (List.hd l1 :: l3)
else (if List.hd l1>List.hd l2 then aux l1 (List.tl l2) (List.hd l2::l3)
      else (if l1 = [] then List.fold_left (fun x y -> y::x) l3 l2
            else if l2=[] then List.fold_left (fun x y -> y::x) l3 l1 else []
     ))
  in List.rev (aux l1 l2 []);;

Frustrimi juaj mund të jetë për shkak të të qenit të kënaqur me gjuhë programimi të ngjashme me C. OCaml mund të jetë zhgënjyese kur përpiqeni të detyroni një stil programimi C në të. Përputhja e modelit është një veçori shumë e fuqishme e OCaml dhe do të thjeshtonte zgjidhjen tuaj:

let rec inter l1 l2 =
  match l1, l2 with
  | [], _ -> l2
  | _, [] -> l1
  | (h1 :: t1), (h2 :: t2) ->
    if h1 <= h2 then
      h1 :: inter t1 l2
    else
      h2 :: inter l1 t2

Modeli i parë thotë "nëse l1 është lista null, atëherë kthejeni l2". Modeli i dytë thotë "nëse l2 është një listë boshe, kthe l1". Kur testohet modeli tre, ne e dimë se të dyja listat nuk janë boshe, kështu që mund të përputhen modele në përmbajtjen e tyre, kështu që nuk ka nevojë të përdorim list.hd, et al. Ne përdorim një deklaratë nëse për të përcaktuar se cila kokë bëhet koka e re dhe cilat bishta përdorim kur përsërisim.

Ndërsa ndiheni më rehat me idiomat OCaml, këto zgjidhje do t'ju vijnë natyrshëm.

14.10.2016
  • Pajtohem për çështjen e stilit: Unë rekomandoj që fillestarët të qëndrojnë larg List.hd. Pasi të jeni mësuar të përdorni modele, është mirë ta rishikoni këtë rregull dhe herë pas here të përdorni List.hd kur është me të vërtetë zgjedhja më e mirë, sigurisht. 15.10.2016
  • Faleminderit për shpjegimin. Unë di për përputhjen e modeleve, por e kam logjikisht më të lehtë të shkruaj kodin në programimin e stilit c. Do të përpiqem të mësohem me të pasi është më pak kod për të shkruar sesa stili im aktual i programimit. 15.10.2016
  • Materiale të reja

    Masterclass Coroutines: Kapitulli-3: Anulimi i korutinave dhe trajtimi i përjashtimeve.
    Mirë se vini në udhëzuesin gjithëpërfshirës mbi Kotlin Coroutines! Në këtë seri artikujsh, unë do t'ju çoj në një udhëtim magjepsës, duke filluar nga bazat dhe gradualisht duke u thelluar në..

    Faketojeni derisa ta arrini me të dhënat false
    A e gjeni ndonjëherë veten duke ndërtuar një aplikacion të ri dhe keni nevojë për të dhëna testimi që duken dhe duken më realiste ose një grup i madh të dhënash për performancën e ngarkesës...

    Si të përdorni kërkesën API në Python
    Kërkesë API në GitHub për të marrë depot e përdoruesve duke përdorur Python. Në këtë artikull, unë shpjegoj procesin hap pas hapi për të trajtuar një kërkesë API për të marrë të dhëna nga..

    Një udhëzues hap pas hapi për të zotëruar React
    Në këtë artikull, do të mësoni se si të krijoni aplikacionin React, do të mësoni se si funksionon React dhe konceptet thelbësore që duhet të dini për të ndërtuar aplikacione React. Learning..

    AI dhe Psikologjia — Pjesa 2
    Në pjesën 2 të serisë sonë të AI dhe Psikologji ne diskutojmë se si makineritë mbledhin dhe përpunojnë të dhëna për të mësuar emocione dhe ndjenja të ndryshme në mendjen e njeriut, duke ndihmuar..

    Esencialet e punës ditore të kodit tim VS
    Shtesat e mia të preferuara - Git Graph 💹 Kjo shtesë është vërtet e mahnitshme, e përdor përpara se të filloj të punoj për të kontrolluar dy herë ndryshimet dhe degët më të fundit, mund të..

    Pse Python? Zbulimi i fuqisë së gjithanshme të një gjiganti programues
    Në peizazhin gjithnjë në zhvillim të gjuhëve të programimit, Python është shfaqur si një forcë dominuese. Rritja e tij meteorike nuk është rastësi. Joshja e Python qëndron në thjeshtësinë,..