lundi 15 février 2021

F# Error: Value cannot be reference and If Else statement

I am converting c# code to f# code. For some reason, the compiler does not like how I call methods in the f# file. I have been stuck with this for days. I dont know why the ReturnClosestInList and findYGivenTwoPointsInSameGraph cannot be referenced. For the if then else, should I use a let to bind the finish? I dont know why it detects it as bool instead of int. Anyone know why I got these errors and perhaps can suggest a better way to write this? I am opened to all sort of suggestions into cleaning up my code. Thanks in advanced!

This is my C# code:

    // find point on graph with given Rc
    private Coordinate GetXY(Dictionary<double, double> cons)
    {
        if (cons.ContainsKey(input))
            return new Coordinate(input, cons[input]);
        else
        {
            //Rc is not found, use interpolation to find point at given Rc.
            List<double> index = ReturnClosestInList(new List<double>(cons.Keys), 0, cons.Count - 1);
            System.Diagnostics.Debug.WriteLine("index1 " + index[0]);
            System.Diagnostics.Debug.WriteLine("index2 " + index[1]);
            return FindClosest(index, cons);
        }
    }

    //formula to find y, given 2 points in the same graph
    private Coordinate FindClosest(List<double> index, Dictionary<double, double> cons)
    {
        double y = cons[index[0]] + ((input - index[0]) / (index[1] - index[0])) * (cons[index[1]] - cons[index[0]]);
        return new Coordinate(input, y);
    }

    //formula to find y, given 2 points from 2 graphs
    private Coordinate FindClosest2(Coordinate p1, Coordinate p2)
    {
        double y = p1.Y + ((givenLine - p1.X) / (p2.X - p1.X)) * (p2.Y - p1.Y);
        //System.Diagnostics.Debug.WriteLine("y is " + y);
        return new Coordinate(givenLine, y);
    }

    //binary search for 2 closest Rc value in the given vi graph.
    private List<double> ReturnClosestInList(List<double> allKey, int begin, int end)
    {
        if (end >= begin)
        {
            int mid = begin + (end - begin) / 2;
            if (allKey[mid] > input) return ReturnClosestInList(allKey, begin, mid - 1);
            return ReturnClosestInList(allKey, mid + 1, end);
        }
        if (end < 0) end = begin + 1;
        if (begin < 0) begin = end + 1;
        if (end > allKey.Count - 1) end = begin - 1;
        if (begin > allKey.Count - 1) begin = end - 1;
        return new List<double> { allKey[begin], allKey[end] };
    }

This is my current f# code. This is my first error. This is my second error. let Keys(map: Map<_, _>) = seq{ for KeyValue(key) in map do yield key }

let findPointXYGivenRc (cons : Map<double, double>) (input : double) = 
    let output = if (cons.ContainsKey(input)) then
                    let c = new Coordinate(cons.[input], input)
                    c
                 else
                    let list = ReturnClosestInList Keys cons 0 (cons.Count - 1) input
                    let c = findYGivenTwoPointsInSameGraph list cons input
                    c                       
    output

let findYGivenTwoPointsInSameGraph (index : Map<int, double>) (cons : Map<double, double>) (input : double) =
    let y = cons.[index.[0]] + (input - index.[0]) / (index.[1] - index.[0]) * (cons.[index.[1]] - cons.[index.[0]])
    let c = new Coordinate(input, y)
    c

let findYGivenTwoPointsFromTwoGraphs (p1 : Coordinate) (p2: Coordinate) (givenLine : double) = 
    let y = p1.Y + (givenLine - p1.X) / (p2.X - p1.X) * (p2.Y - p1.Y);
    let c = new Coordinate(givenLine, y)
    c

let rec ReturnClosestInList (allKey : List<double>) (start : int) (finish : int) (input : double)= 
    if(finish >= start) then
        let mid = start + (finish - start) / 2
        if(allKey.[mid] > input) then
            ReturnClosestInList allKey start (mid - 1) input
        else ReturnClosestInList allKey (start + 1) mid input

    finish = if finish < 0 then 
                start + 1
             else finish

Aucun commentaire:

Enregistrer un commentaire