Agda stdlib List max - list

I'm trying to get the max element of a Data.List:
listMax : max ℕ (2 ∷ 1 ∷ []) ≟ 2
listMax = ?
but don't understand why I'm getting this error:
Set !=< (Relation.Binary.Bundles.TotalOrder _b_20 _ℓ₁_21 _ℓ₂_22)
when checking that the expression ℕ has type
Relation.Binary.Bundles.TotalOrder _b_20 _ℓ₁_21 _ℓ₂_22
I'm guessing that ℕ should instead be something of type
Relation.Binary.Bundles.TotalOrder _b_20 _ℓ₁_21 _ℓ₂_22
but I don't know how to get something of that type and why is it needed to get the max element.
EDIT
Looking at the signature for max in Data.List.Extrema I see:
max : B → List B → B
and I see that B is defined here
open TotalOrder totalOrder renaming (Carrier to B)
I'm not sure why ℕ can't be a Carrier.
I also found in Data.Fin.Properties:
≤-totalOrder : ℕ → TotalOrder _ _ _
and tried
listMax : {n : ℕ} → max (≤-totalOrder n) (2 l.∷ 1 l.∷ l.[]) ≡ 2
but am now getting this error:
List _A_27 !=< Fin n
when checking that the inferred type of an application
List _A_27
matches the expected type
Relation.Binary.Bundles.TotalOrder.Carrier (≤-totalOrder n)
Thanks!

After finding this example in Data.String.Base:
rectangle : ∀ {n} → Vec (ℕ → String → String) n →
Vec String n → Vec String n
rectangle pads cells = Vec.zipWith (λ p c → p width c) pads cells where
sizes = List.map length (Vec.toList cells)
width = max 0 sizes
I found out that the call to max should look like
max 0 (2 l.∷ l.[])
and also found that I was missing the import:
open import Data.List.Extrema ℕₚ.≤-totalOrder
For a reason I don't yet know, using this import doesn't give the error:
ℕ != (Relation.Binary.TotalOrder _b_26 _ℓ₁_27 _ℓ₂_28)
when checking that the expression 0 has type
Relation.Binary.TotalOrder _b_26 _ℓ₁_27 _ℓ₂_28
that I was getting from doing this import:
open import Data.List.Extrema (max)
I'm still curious as to what makes the import
open import Data.List.Extrema ℕₚ.≤-totalOrder
work.

Related

f# concatenate list of objects

type Googol = {
number : float
power : float
result : float
}
let generatePowers (n:float) : list<Googol> =
let rec powerInner (n:float) (p:float) (acc : list<Googol>) =
match n with
| p when p <= 1.0 -> acc
| p when p > 1.0 -> powerInner n (p-1.0) ([{ number=n; power=p; result=n**p}]#acc)
let rec numberInner (n:float) (acc : list<Googol>) =
match n with
| n when n <=1.0 -> acc
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
numberInner n []
ProjectEuler.fsx(311,50): error FS0001: This expression was expected to have type
'Googol list'
but here has type
'Googol list -> Googol list'
I am trying to solve this problem -> https://projecteuler.net/problem=56 | but for this I need to generate powers below n < 100. When I try to concatenate [{ number=n; power=p; result=n**p}]#acc
these lists I get the error above. Explain please why error says 'Googol list -> Googol list' is in the function, does I plug a function as a parameter to the function or I plug the actual list when just after concatenation. Is # a function?
This looks like homework or practice, so first I'll give some hints to move on. Finally I'll show a version that seems to work, and then tell how I would approach the problem.
The task is to find the number a ** b, for a and b less than 100, that has the highest sum of its own digits.
The first problem is that float won't give us all the digits of a ** b, so that type is useless to solve the problem. To fix that, we turn to the BigInteger type, and the BigInteger.Pow function. Then we get a 1 followed by 200 zeroes if we run the following snippet, just like it says in the problem description.
let x: bigint = BigInteger.Pow (100I, 100)
let x: string = string x
printfn "s=%s" x
To get useful results, change the Googol type so that it uses bigint, except for power that should be an int.
Why are the functions powerInner and numberInner inside the function generatePowers? This doesn't seem to have a specific purpose, so I suggest moving them out to make this clearer.
The function powerInner do a match on n, but then goes on to name the results p, which shadows the p parameter so that it is unused. Ok, the intention here is probably to match on p rather than n, so just fix that, and then the shadowing of the p parameter is perfectly fine.
The tests first on <= 1 and then on > 1 causes incomplete matches. If the first line checks that the number is less or equal to one, then it must the greater than one in the next line. So just use n -> without the when to fix that. I also suspect you want to test <= 0 instead of 1.
This
[{ number=n; power=p; result=n**p}]#acc
can be just
{ number=n; power=p; result=n**p } :: acc
and here
(powerInner n [])
I suspect you just need a starting value for the power, which would be 99
(powerInner n 99 [])
SPOILER WARNING
After a bit of tinkering, this is what I ended up with, and it seems to print out a useful list of numbers. Note that in order to not run through all 99 by 99 results with printouts, I've used low starting numbers 3 and 5 for the countdowns here, so we get some simple printout we can study for analysis.
type Googol = { number: bigint; power: int; result: bigint }
let rec powerInner (n: bigint) (p: int) (acc: Googol list) =
match p with
| p when p <= 0 -> acc
| p ->
let newNumber = { number = n; power = p; result = n ** p }
printfn "newNumber=%0A" newNumber
powerInner n (p - 1) (newNumber :: acc)
let rec numberInner (n: bigint) (acc: Googol list) =
match n with
| n when n <= 0I -> acc
| n -> numberInner (n - 1I) ((powerInner n 5 []) # acc)
let generatePowers (n: bigint) : Googol list =
numberInner n []
let powers = generatePowers 3I
I'm not sure if this solution is correct. I'd do it differently anyway.
I would simply loop through a and b in two loops, one inside the other. For each a ** b I would convert the result to a string, and then sum the digits of the string. Then I'd simply use a mutable to hold on to whichever result is the highest. The same could be achieved in a more functional way with one of those fancy List functions.
You're missing a parameter here:
| n when n >1.0 -> numberInner (n-1.0) ((powerInner n [])#acc)
^^^^^^^^^^^^^^^
here
powerInner is defined with three parameters, but you're only passing two.
In F# it is not technically illegal to pass fewer parameters than defined. If you do that, the result will be a function that "expects" the remaining parameters. For example:
let f : int -> int -> string
let x = f 42
// Here, x : int -> string
let y = x 5
// Here, y : string
So in your case omitting the last parameter makes the resulting type Googol list -> Googol list, which then turns out to be incompatible with the type Googol list expected by operator #. Which is what the compiler is telling you in the error message.

Agda stdlib Vec fromList of list with arbitrary length

I'm trying to use Data.Vec fromList on a Data.List of arbitrary length:
natListToVec : {n : ℕ} → List ℕ → Vec ℕ n
natListToVec nats = v.fromList nats
but get the error:
l.foldr (λ _ → suc) 0 nats != n of type ℕ
when checking that the expression fromList nats has type Vec ℕ n
When I try with a List that has a known length I don't get any issue:
ListWith2ToVec : v.fromList (2 l.∷ l.[]) ≡ 2 v.∷ v.[]
ListWith2ToVec = refl
I'm guessing the problem is that with this type signature:
{n : ℕ} → List ℕ → Vec ℕ n
I don't specify that n must be the length of the List ℕ.
How would I do this?
Thanks!
You can simply use the length function in the type signature. You also have to name the argument of type list to refer to it, like so:
natListToVec : (xs : List ℕ) → Vec ℕ (length xs)
[...]

Agda: return the last element of a List

When I check in agda-stdlib/src/Data/List/Base.agda I see that there is no last function but I see in agda-stdlib/src/Data/Vec/Base.agda a function for last.
When I try to use it though I get some type errors that I'm unsure I understand.
This is how I'm trying to call it:
last (fromList todos)
where
todos : List Todo
and
record Todo : Set where
field
text : String
completed : Bool
id : ℕ
The error I get is
Data.List.foldr (λ _ → suc) 0 todos != suc _n_31 of type ℕ
when checking that the expression fromList todos has type
Data.Vec.Vec Todo (1 + _n_31)
I'm guessing it has to do with the fact that last has this signature:
last : ∀ {n} → Vec A (1 + n) → A
But I'm confused because when I do C-c C-l on:
last (fromList ?)
I get this goal
?0 : List Todo
which I thought todos satisfied.
What should I change here to make it pass this error?
Or is there another way to get the last element of a List?
Thanks!
EDIT
I tried a different route and decided to replace the Vec with List. However I'm getting another error I don't quite understand when I try to do
Todo.completed (last (todos ∷ʳ record { text = text ; completed = false ; id = 1 }))
≡⟨⟩
Todo.completed (record { text = text ; completed = false ; id = 1 })
false !=
Todo.completed
(last
(todos ∷ʳ record { text = text ; completed = false ; id = 1 })
| Data.Vec.initLast
(todos ∷ʳ record { text = text ; completed = false ; id = 1 }))
of type Bool
when checking that the inferred type of an application
false ≡ _y_45
matches the expected type
Todo.completed
(last
(todos ∷ʳ record { text = text ; completed = false ; id = 1 }))
≡ false
I'm not sure what the error message is saying here.
EDIT
I tried to simplify the problem down further to
AddNat : ∀ {n : ℕ} → (Vec ℕ n) → (Vec ℕ (1 + n))
AddNat numbers = numbers ∷ʳ 1
AddNatLastAddedElementIsNat :
∀ {n : ℕ} (numbers : Vec ℕ (1 + n)) →
last (AddNat numbers) ≡ 1
AddNatLastAddedElementIsNat numbers =
begin
last (AddNat numbers)
≡⟨⟩
last (numbers ∷ʳ 1)
≡⟨⟩
1
∎
but I still get a similar error:
1 != (last (numbers ∷ʳ 1) | Data.Vec.initLast (numbers ∷ʳ 1)) of
type ℕ
when checking that the expression 1 ∎ has type
last (numbers ∷ʳ 1) ≡ 1
Why does the last (numbers ∷ʳ 1) show up as type (last (numbers ∷ʳ 1) | Data.Vec.initLast (numbers ∷ʳ 1))? Does | indicate it is a sum type and I would need to pattern match on both cases? Thanks!
The goal in fromList ?0 does have type List Todo, but since fromList ?0 has type Vec _ (length ?0) you'll get an error if the typechecker concludes that there can't be no n such that length ?0 is (definitionally) equal to 1 + n.
In your case that happens once you say that ?0 := todos, something like ?0 := x ∷ todos would have worked instead.
Generally a function like last needs to know that the list or vectors is non-empty, an alternative is to define a function that returns Maybe A instead of A though.

how to get nth element from List in f# using option

Im new to f# and i'm trying to make this exercise:
"Implement a function"
let rec nth(n : int) (l : List<'a>) : Option<'a> =
that returns the element in position n in l. The function must handle appropriately the case where the index is invalid
this is my current code but I'm kinda stuck:
let rec nth (n : int) (l : List<'a>) : Option<'a> =
if n > l.Length then
None
else
match l with
| [] -> None
Thanks for the help!
There is a built-in function List.tryItem
let rec nth(n : int) (l : List<'a>) : Option<'a> =
l |> List.tryItem n
Can you use any functionality provided by the core library at all? If so, I suggest the following function:
let nth (n : int) (l : 'a list) : 'a option =
if n < 1 || n > l.Length then None else Some l.[n - 1]
This just checks whether the index is within permitted boundaries, then returns the element at the appropriate index. The index-item operator is zero-based, therefore we need to subtract one from the number passed into the function, and the list iteration is done by the compiler behind the scenes.
If you need to do it completely manually, I suggest the following function:
let nth (n : int) (l : 'a list) : 'a option =
let rec inner i = function
| [] -> None
| x :: _ when i = 0 -> Some x
| _ :: xs -> inner (i - 1) xs
if n < 1 then None else inner (n - 1) l
This checks the lower boundary, and if it is all right, starts to iterate the list using an inner function, and decrementing the index until it is zero so it knows it reached the right index. If the list is shorter, None is returned.

Why does pattern with variable not match?

I'm writing a code that can find the median of a list, and I cannot use rec and should use List.fold_left/right. I wrote the following code, which should work.
It finds the length of the list, if it's an odd number like 5, then it sets len1, len2 to 2, 3, if it's an even number like 6, then it sets len1, len2 to 2, 3.
Then for each member in the list I match the number of those elements that are less than it.
However, the following pattern matching always math lessNum elmt to len1 - can someone tell me why it is so?
let median (lst : int list) : float option =
let len = List.length lst in
if lst = [] then None
else
let len1, len2 = (len - 1) / 2, (len + 1) / 2 in
let lessNum a =
List.length (List.find_all (fun n -> n < a) lst) in
let answer = List.fold_left (fun accm elmt ->
match (lessNum elmt) with
| len1 -> accm + elmt
| len2 -> failwith "len2"
| _ -> failwith "other"
) 0 lst in
if len mod 2 = 0
then Some ((float_of_int answer) /. 2.0)
else Some (float_of_int answer)
An identifier appearing in a pattern always matches, and binds the corresponding value to the identifier. Any current value of the identifier doesn't matter at all: the pattern causes a new binding, i.e., it gives a new value to the identifier (just inside the match).
# let a = 3;;
val a : int = 3
# match 5 with a -> a;;
- : int = 5
# a;;
- : int = 3
#
So, your match statement isn't doing what you think it is. You'll probably have to use an if for that part of your code.
Update
Here's how to use an association list to approximate the function f in your followup question:
let f x = List.assoc x [(pat1, ans1); (pat2, ans2)]
This will raise a Not_found exception if x is not equal to pat1 or pat2.
(I think your Python code is missing return.)