outra linguagem funcional mas com componentes de linguagem imperativa
como em Haskell (homogênea) mas separado por ;
let a = [1; 2; 3; 7; 5; 1]
No pattern matching e na construção, o operador que separa
head
de tail
é ::
e não
:
(no Haskell)
let b = 7 :: a
Como em Haskell - mesma sintaxe sem parenteses e virgula separando função de argumento
let f x y = 2*x+y
f 4 3
precisa usar a palavre rec
let rec gera n =
if n=0 then []
else n :: gera (n-1)
let rec pertence x lista =
match lista with
| [] -> false
| a::_ when x = a -> true
| _::as -> pertence x as
let ... in
para definir funções e variáveis
locais
List.map
e List.fold_left
em vez de
map
e foldl
=
que é tambem o
operador para “definição de função” (super confuso) (veja o código do
pretence acima)Haskell
f _ = 3
f (1/0) -> 3
OCAML
let f _ = 3
f (1/0) -> erro divisão por 0
não converte de int para float automaticamente
tem operações diferentes para int
e
float
: +
para int, +.
para
float
let quit_loop = ref false in
while not !quit_loop do
print_string "Have you had enough yet? (y/n) ";
let str = read_line () in
if str.[0] = 'y' then
quit_loop := true
done;;
quit_loop
é um “apontador” (ref
) para
bool
!quit_loop
é o valor de
quit_loop
:=
é atribuição
read_line
tem tipo unit -> string
e
o ()
o único dado to tipo unit
read_line ()
é escrito como read_line()
que se parace com uma função sem argumentos na sintaxe mais
tradicional.
Arrays sao vetores modificáveis
let add_vect v1 v2 =
let len = min (Array.length v1) (Array.length v2) in
let res = Array.make len 0.0 in
for i = 0 to len - 1 do
res.(i) <- v1.(i) +. v2.(i)
done;
res;;
note a operação <-
(e nao o
:=
)
note tambem o for
que é apenas para gerar
números.
nao existe o break
para sair de um loop
Existe um tipo unit
ou ()
que é um
comando (que não retorna nada - o importante é seu efeito
colateral)
voce pode usar o padrão
comando;
comando;
..
comando;
expressão
no lugar de expressões.
Veja de novo
let quit_loop = ref false in
while not !quit_loop do
print_string "Have you had enough yet? (y/n) "; --> comando
let str = read_line () in
if str.[0] = 'y' then -> um if sem else!
quit_loop := true -> comando
done;;
me parece que o while
é um comando tambem que retorna
()
https://markkarpov.com/post/haskell-vs-ocaml.html
(fonte https://learn.microsoft.com/en-gb/dotnet/fsharp/
Bem parecido com OCaml
let doubleIt x = 2*x
let doubleIt = fun n -> 2 * n
fun n
é uma lambda expression
-sintaxe de metodos para alguns tipos pre definidos
let str = "F#"
let lowercase = str.ToLower()
// This example uses a record pattern.
type MyRecord = { Name: string; ID: int }
let IsMatchByName record1 (name: string) =
match record1 with
| {MyRecord.Name = nameFound; MyRecord.ID = _;} when nameFound = name -> true
| _ -> false
let mutable x = 1
x <- x + 1
<-
atribuicao
listas [1; 2; 3 ]
arrays como tipo basico , com representacao sintatica
[| 1;2;3 |]
e mutavel.
unidades metricas para os valores https://learn.microsoft.com/en-gb/dotnet/fsharp/language-reference/units-of-measure o compilador checa unidades corretas (inclui conversão??) - talvez exista algo assim tambem em haskell?
OO (uma classe na verdade é um novo tipo)
module DefiningGenericClasses =
type StateTracker<'T>(initialElement: 'T) =
/// This internal field store the states in a list.
let mutable states = [ initialElement ]
/// Add a new element to the list of states.
member this.UpdateState newState =
states <- newState :: states // ***use the '<-' operator to mutate the value.***
/// Get the entire list of historical states.
member this.History = states
/// Get the latest state.
member this.Current = states.Head
/// An 'int' instance of the state tracker class. Note that the type parameter is inferred.
let tracker = StateTracker 10
// Add a state
tracker.UpdateState 17