简体   繁体   中英

This expression was expected to have type unit

I have the following code. in this line

 if min<=0  then     min <- List.nth list i |>ignore

i have 2 errors. first in 0 it is

 This expression was expected to have type
    unit    
but here has type
    int

and then in i it is

This expression was expected to have type
    unit    
but here has type
    int

* I have also seen this and tried ignore, but it doesn't work

let replace touple2=
   let first  (a,_,_,_,_)=a
   let second (_,b,_,_,_)=b
   let third  (_,_,c,_,_)=c
   let forth  (_,_,_,d,_)=d
   let fifth  (_,_,_,_,e)=e
   let sortedlist list= List.sort(list)

   let GetMin list=
        list |> List.rev |> List.head
        let mutable min=list.Head
        let mutable i=1
        for i in list do     
            if min<=0  then     min <- List.nth list i |>ignore

        min 

   let GetMax list=list |> List.rev |> List.head

   let A=first  touple2
   let B=second touple2
   let C=third  touple2
   let D=forth  touple2
   let E=fifth  touple2
   let mylist=[A;B;C;D;E]
   let L=sortedlist mylist

   let m1=GetMax L
   printfn "%d"  m1

let touple3= 14,6,18,76,76
replace touple3

You do not need the ignore - if you are using assignment, it returns unit and so you do not have any return value that would have to be ignored:

if min <= 0 then min <- List.nth list I

That said, this is not very functional approach. So looking into some basic F# book or watching a few talks might help you get started with the langauge in a more F# style.

You just need parentheses to make your intentions clear to the compiler:

if min <= 0 then (min <- List.nth list i) |> ignore

An if without an else in F# is a shorthand for:

if condition then doSomething else ()

It means the result of whatever is inside the doSomething block must be of type unit . Since an assignment in F# is an expression, your code was returning min , an int value. This explains your first error.

The above happened because, without the parenthesis, the pipe operator was using last parameter os List.nth , the i as the parameter to ignore

The first problem is list |> List.rev |> List.head causing the compiler to infer list to be of type unit . If you delete that line (as it's meaningless anyways, F# lists are immutable, so you are computing an unused value), list is correctly inferred to have type int list which makes the first error go away (if we also use List.head list instead of list.Head to make type inference happy).

Then, a second error appears on this line if min<=0 then min <- List.nth list i |>ignore which makes sense, as an assignment to a mutable variable should leave nothing to |> ignore . So lets get rid of that, fix the deprecation warning and add a bit of formatting... this compiles:

let replace touple2 =
   let first  (a,_,_,_,_) = a
   let second (_,b,_,_,_) = b
   let third  (_,_,c,_,_) = c
   let forth  (_,_,_,d,_) = d
   let fifth  (_,_,_,_,e) = e
   let sortedlist list= List.sort(list)

   let GetMin list=
        let mutable min = List.head list
        let mutable i = 1
        for i in list do     
            if min <= 0 then min <- List.item i list

        min 

   let GetMax list = list |> List.rev |> List.head

   let A = first  touple2
   let B = second touple2
   let C = third  touple2
   let D = forth  touple2
   let E = fifth  touple2
   let mylist = [A;B;C;D;E]
   let L = sortedlist mylist

   let m1 = GetMax L
   printfn "%d" m1

let touple3 = 14,6,18,76,76
replace touple3

Still, it doesn't really look F#-ish. How about this (including wild guesses what you want to achieve):

let printMinMax (a, b, c, d, e) =

    let minPositive sortedList = 
        sortedList |> List.fold (fun m e -> if m <= 0 then e else m) sortedList.Head

    let max sortedList = sortedList |> List.last

    let sortedList = [ a; b; c; d; e ] |> List.sort

    printfn "min %d, max %d" (minPositive sortedList) (max sortedList)

let t1 = 14, 6, 18, 76, 76
printMinMax t1

let t2 = -1, -5, 5, 16, 12
printMinMax t2

This could be improved further, but I fear the connection to the original becomes even less obvious (and it expects at least one positive value to be present):

let minMax (a, b, c, d, e) =
    let l = [ a; b; c; d; e ] |> List.sortDescending
    let positiveMin = l |> List.findBack ((<) 0)
    let max = l.Head
    positiveMin, max

let t1 = 14, 6, 18, 76, 76
let t2 = -1, -5, 5, 16, 12

let test t =
    let min, max = minMax t
    printfn "min (positive) %d, max %d" min max

test t1
test t2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM