F# if statement function with parameter syntax - if-statement

The issue is: I cannot figure out what the error is refering to when it diplays
Here is the error:
source_file.fs(10,5): error FS0010: Unexpected keyword 'if' in binding. Expected '=' or other token.
And I've been researching this error and proper syntax for a good while.
Now what I want to do, I hope, is obvious from the general look of the program.
Knowing the correct syntax would be great as microsofts docs are not great.
Seeing as this is case, I just don't understand what could be wrong.
open System
let one = "one"
let two = "two"
if oneortwo one then printfn one + " 1"
else printfn two + " 2"
let oneortwo(a : string)
if a = "one" then return true
elif a = "two" then return false
return false

F# is an expression based language, which means that everything has a value (returns something). F# is also statically typed, so everything returned is of a specific type.
Since everything is an expression, the return keyword is not used. The final expression in a function body is the returned value.
This goes also for if ... then ... else: every branch must return a value and be of the same type.
The correct syntax for your function is
let oneortwo a =
if a = "one" then true
else false
An excellent source of learning F# is Scott Wlaschin's site F# for fun and profit

Related

Power Query: try ... otherwise on list item expression

Why does catching the following index-error fail:
let
Source = "abc",
letter_list = Text.ToList(Source),
try_on_index_error = try letter_list{5}
in
try_on_index_error
The try statement does not return an Error record. It keeps throwing the error as if no try was present.
In this case it works as expected, returning an Error record as a valid result of the query:
let
Source = "abc",
try_another_error = try Source + 1,
Error = try_another_error[Error]
in
Error
https://learn.microsoft.com/en-us/power-query/handlingerrors#catching-an-error-with-try-and-otherwise
https://learn.microsoft.com/en-us/powerquery-m/m-spec-consolidated-grammar#error-handling-expression
It is naturally hard to answer questions on the behavior of closed-source software. However, the comment by Ron Rosenfeld solved my trouble:
letter_list = List.Buffer(Text.ToList(Source))
The docs (last paragraph in chapter Evaluation) explain the unexpected behavior: Lazy evaluation is done for lists, records and let-expressions. As seen above, in case of lazy evaluation, try statement falls back to syntax checking, supposedly.

SML getting an unbound variable or constructor error when everything seems right

I'm trying to figure out mutual recursion. I have this code:
fun take(L)=
if L=nil then nil
else hd(L) :: skip(tl(L))
AND
fun skip(L)=
if L=nil then nil
else take(tl(L));
but it gives me these errors:
stdIn:54.14-54.18 Error: unbound variable or constructor: skip
stdIn:55.1-55.4 Error: unbound variable or constructor: AND
What am I doing wrong?
Your immediate error is because Standard ML is case-sensitive, and all of its reserved words are in lowercase; so you need to write and rather than AND.
Additionally, fun introduces an entire declaration, not an individual binding, meaning that you need to remove the extra fun after and.
Lastly, your functions currently require the list to have an equality type (such as int list or string list), which may not be a deal-breaker, but given what the functions actually do, there's really no reason they can't support non-equality types such as real list. To achieve that, you should match the parameter against the pattern nil, instead of testing whether the parameter equals nil. (More generally, you should use pattern-matching in more places; you have no reason to call hd and tl.)
Putting it together:
fun take nil = nil
| take (h::t) = h :: skip t
and skip nil = nil
| skip (h::t) = take t

Explanation why a list with different types is a valid Haskell expression needed

So in an exercise I am given a list like ["xyz", True, 42]. The question was if that is a valid expression in Haskell and what the type of that expression is.
A list can only hold homogenous types but the type of "xyz"is [Char], the type of True is Bool and the type of 42 is Num p => p. That is different types so I can't put them into a list.
That's what I thought. But the given answer to that exercise is "Yes, it is a valid expression. Show-instance!."
Why is it a valid expression although the types of the list elements are different and what is meant with show-instance? I'm thinking of something like superclasses from object oriented languages but I thought this is not how Haskell works.
If we are allowed to define some more context, we can make this a valid expression, for instance with:
import Data.String(IsString(fromString))
instance IsString Bool where
fromString [] = False
fromString _ = True
instance Num Bool where
(+) = (||)
(*) = (&&)
abs = id
signum = id
fromInteger 0 = False
fromInteger _ = True
negate = not
(here I used the truthiness of Python to convert from an Integer and String literal)
Then we can write it with the OverloadedStrings pragma:
{-# LANGUAGE OverloadedStrings #-}
the_list = ["xyz", True, 42]
This will then be equivalent to:
Prelude Data.String> ["xyz", True, 42]
[True,True,True]
But note that the list still contains only Bools, we only made Bool an instance of IsString and Num to enable us to convert string literals and number literals to Bools.
A list of heterogeneous types is not possible in Haskell, and since by default a Bool is not a Num, we thus can not parse that expression without adding some extra magic.
An additional note is that it is valid Haskell grammar: syntactically there is nothing wrong, it is only in the next stage of the compiler: type checking, etc. that it will raise errors, since the syntax is nonsensical.
My lecturer gave me a hint to check for Existential types in Haskell.
I produced a working example from the description from the link above:
{-# LANGUAGE ExistentialQuantification #-}
module Main where
data Showable = forall a . Show a => MkShowable a
pack:: Show a => a -> Showable
pack a= MkShowable a
instance Show Showable where
show (MkShowable a) = show a
hlist :: [Showable]
hlist = [pack "xyz", pack True, pack 42]
main :: IO ()
main = do
putStrLn "Heterogenous list 'camouflaged' as Showable:"
print hlist
This works and produces indeed the input from the exercise. The datatype extension for Existential Quantification in the first line is necessary.
My explanation (I might have gotten something wrong though):
I create a new type Showablewith one constructor MkShowable that takes any value a as long as it is in typeclass Show and thus makes a Showable out of it.
The method pack makes a Show a become a Showable by using the constructor MkShowable I described in 1.
Showable is made an instance of Show-typeclass and tells that if a Showable(MkShowable a) is to be shown, simply show a. So we can easily print our Showables.
Furthermore I created a (heterogenous) list hlist of type [Showable]and packed the values from my example into it, using pack. The list is printed in the main function.
This really reminds me of object-oriented programming.

Ocaml Error: Unbound record field label length

This is the error I'm getting and I have no idea why: "Error: Unbound record field label length "
Does anyonw know?
let rastavi str =
let sublist = ref [] in
let list = ref [] in
for i = ((str.length str)1) [down]to 0 do
if str.[i] =' ' then (str.[i] :: !sublist)
else (list := (!sublist:: !list)) sublist = []
done ;;
You're using OO notation to get the length of a string. OCaml uses functional notation. So it looks like this:
String.length str
Not like this:
str.length (* OO notation, not in OCaml *)
Edit:
Side comment: this solution is very much an imperative take on the problem. If you're trying to learn the FP mindset, you should try to think recursively and immutably. Since this looks like homework, it's very likely a functional solution is what you want.
But here are a few other problems in your original code:
You have two expressions next to each other with nothing in between. If you want to "do" two things, you need to separate them with a semicolon ; (however, this is imperative style)
You're using = which compares two values for equality. If you want to assign a value to a reference you need to use :=. (Imperative style, again.)

Simple SML code error

I have just started learning SML and still in the process of making sense of its error messages.
when trying to input the function definition below
val rec : real->real = fn 0.0 => 0.0 | n:real => 1.0/n;
i get the following error :
stdIn:25.9-25.17 Error: syntax error: deleting COLON ID ARROW
stdIn:25.24-25.33 Error: syntax error: deleting FN REAL DARROW
stdIn:25.38 Error: syntax error found at BAR
can someone point out what i am doing wrong ?
thank you.
You have two errors in your code:
Between val rec and the type annotation there should be the name of the value you're defining.
You can't use pattern matching on reals. Since reals are inexact, they aren't equality types, so you can't use = on them either. You need to use Real.== to compare reals for equality (or better: don't compare them for equality, but compare them against some delta instead).