Related
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.
I'm trying to write a reverse vector function in agda, and am running into the following stumbling block
Goal: Vec Nat (suc n)
Have: Vec Nat (n +N 1)
If I understand correctly, these values aren't definionally equal. Here is the reverse function.
vReverse : {X : Set} {n : Nat} → Vec X n → Vec X n
vReverse [] = []
vReverse (x ,- x₁) = {!(vReverse x₁) +V (x ,- [])!}
How can I overcome this, if possilbe, without refactoring the code. If a refactor is necessary, how can one generally avoid these pitfalls a priori? Here is the rest of the code.
data Nat : Set where
zero : Nat
suc : Nat -> Nat -- recursive data type
{-# BUILTIN NATURAL Nat #-}
_+N_ : Nat -> Nat -> Nat
zero +N y = y
suc x +N y = suc (x +N y) -- there are other choices
data Vec (X : Set) : Nat -> Set where -- like lists, but length-indexed
[] : Vec X zero
_,-_ : {n : Nat} -> X -> Vec X n -> Vec X (suc n)
infixr 4 _,-_ -- the "cons" operator associates to the right
_+V_ : {X : Set}{m n : Nat} -> Vec X m -> Vec X n -> Vec X (m +N n)
[] +V xs = xs
(x ,- xs) +V [] = x ,- xs +V []
(x ,- xs) +V x₁ ,- ys = x ,- xs +V x₁ ,- ys
The idea is that you can transform an element of type P x into an element of type P y provided you can prove x ≡ y. Let me guide you through this process step by step. Here is the base code you provided, which I have not refactored as you requested.
data Nat : Set where
zero : Nat
suc : Nat -> Nat -- recursive data type
{-# BUILTIN NATURAL Nat #-}
_+N_ : Nat -> Nat -> Nat
zero +N y = y
suc x +N y = suc (x +N y) -- there are other choices
infixl 5 _+N_
data Vec (X : Set) : Nat -> Set where -- like lists, but length-indexed
[] : Vec X zero
_,-_ : {n : Nat} -> X -> Vec X n -> Vec X (suc n)
infixr 4 _,-_ -- the "cons" operator associates to the right
However, your concatenation function was incorrect and it didn't terminate so here is the corrected version.
_+V_ : {X : Set}{m n : Nat} -> Vec X m -> Vec X n -> Vec X (m +N n)
[] +V vs = vs
(x ,- xs) +V vs = x ,- (xs +V vs)
The reason why we don't need to do any substitution in this function is because suc n + m is definitionally equal to suc (n + m).
Since you've defined your own naturals and your own addition, I'm assuming you want to redefine everything by yourself. According to this assumption, you'll need to define propositional equality, which is done as follows:
data _≡_ {a} {A : Set a} (x : A) : A → Set a where
refl : x ≡ x
infix 1 _≡_
From this definition, we can define the substitution that was mentioned in the preamble of this answer, as well as in a comment of your question:
subst : ∀ {a b} {A : Set a} {x y : A} (P : A → Set b) → x ≡ y → P x → P y
subst _ refl p = p
In your reverse function, the problem lies in the fact that n + 1 is not definitionally equal to suc n. Which is why we need a property to establish this fact, which we can then feed to our substitution mechanism. This proof requires the congruence of the propositional equality we defined, as follows:
cong : ∀ {a b} {A : Set a} {B : Set b} (f : A → B) {x y} → x ≡ y → f x ≡ f y
cong _ refl = refl
n+1≡sn : ∀ {n} → n +N 1 ≡ suc n
n+1≡sn {zero} = refl
n+1≡sn {suc _} = cong suc n+1≡sn
We now have all the required elements to write your vReverse function:
vReverse : ∀ {X n} → Vec X n → Vec X n
vReverse [] = []
vReverse (x ,- x₁) = subst (Vec _) n+1≡sn ((vReverse x₁) +V (x ,- []))
To go Further, you can use the same process to build the usual reverse function which is more efficient (linear complexity). I took the liberty to do this for you, since it shows more examples of usage of subst.
n+sm≡sn+m : ∀ {n m} → n +N suc m ≡ suc (n +N m)
n+sm≡sn+m {zero} = refl
n+sm≡sn+m {suc _} = cong suc n+sm≡sn+m
reverse-better-aux : ∀ {X n m} → Vec X n → Vec X m → Vec X (n +N m)
reverse-better-aux [] v₂ = v₂
reverse-better-aux (x ,- v₁) v₂ = subst (Vec _) n+sm≡sn+m (reverse-better-aux v₁ (x ,- v₂))
n+0≡n : ∀ {n} → n +N 0 ≡ n
n+0≡n {zero} = refl
n+0≡n {suc _} = cong suc n+0≡n
reverse-better : ∀ {X n} → Vec X n → Vec X n
reverse-better v = subst (Vec _) n+0≡n (reverse-better-aux v [])
I am trying to convert a list to a data.map so that from a list like:
mylist = ["one","one","two","three","two","two","three","four","four","four","four","five","five","two"]
I get something like:
("one", 2) ("two", 4) ...
I am trying following code:
import qualified Data.Map as Map
import Data.List
list2dict [] mymap = print mymap
list2dict [y:ys] mymap = do
if (Map.lookup y mymap) /= Nothing
then list2dict [ys] $ Map.insert y ((Map.lookup y) + 1) mymap
else list2dict [ys] $ Map.insert y 1 mymap
mylist = ["one","one","two","three","two","two","three","four","four","four","four","five","five","two"]
main = do
list2dict (sort mylist) $ Map.empty
However, I am getting following error:
soq_list2dict.hs:5:1: error:
• Non type-variable argument
in the constraint: Show (Map.Map k a -> Maybe a)
(Use FlexibleContexts to permit this)
• When checking the inferred type
list2dict :: forall a k.
(Show (Map.Map k a -> Maybe a), Show k, Ord k,
Num (Map.Map k a -> Maybe a), Eq (Map.Map k a -> Maybe a)) =>
[[k]] -> Map.Map k (Map.Map k a -> Maybe a) -> IO ()
How can this be solved?
Edit: using (y:ys) instead of [y:ys] gives following error:
soq_list2dict.hs:5:1: error:
• Occurs check: cannot construct the infinite type: k ~ [k]
Expected type: [[k]] -> Map.Map k (Map.Map k a -> Maybe a) -> IO ()
Actual type: [k] -> Map.Map k (Map.Map k a -> Maybe a) -> IO ()
• Relevant bindings include
list2dict :: [[k]] -> Map.Map k (Map.Map k a -> Maybe a) -> IO ()
(bound at soq_list2dict.hs:5:1)
Willem Van Onsem already pointed out the first problem in a comment: you used [y:ys] instead of (y:ys). The second problem is that you used [ys] instead of just ys in two places. The third problem is that you say ((Map.lookup y) + 1), which creates a nonsensical type. (Even if you had used ((Map.lookup y mymap) + 1) instead, which is closer to correct, you still would have just gotten a different error.) This way will work instead:
list2dict (y:ys) mymap = case Map.lookup y mymap of
Just x -> list2dict ys $ Map.insert y (x + 1) mymap
Nothing -> list2dict ys $ Map.insert y 1 mymap
Note that I pattern-match on the Maybe rather than testing it with if and then trying to extract the value separately after that.
You made a classic error: a non-empty list has as pattern (x:xs) (notice the empty brackets). But you make things too complicated here.
You can implement this with a foldr pattern, that can convert any (Ord a, Foldable f) => f a to a (Ord a, Integral i) => Map a i:
import Data.Map(Map, alter, empty)
import Data.Maybe(maybe)
toCounter :: (Ord a, Foldable f, Integral i) => f a -> Map a i
toCounter = foldr (alter (Just . maybe 1 (1+))) empty
We thus start with an empty map, and for each item in the Foldable, we perform an alter where, in case the item already exists (then it gives us a Just n, we return a Just (n+1), and for a Nothing we fallback on 1.
Since it works on (Ord a, Foldable f) => f a, you can make a "counter" for anything of a type that is an instance of the Ord typeclass, and is stored in a object of a type that is an instance of a Foldable. So it can count items in a list, Maybe (well this has exactly one or no item), a Tree, etc.
For example:
*Main> toCounter ["one","one","two","three","two","two","three","four","four","four","four","five","five","two"]
fromList [("five",2),("four",4),("one",2),("three",2),("two",4)]
A shorter version, that works on lists is one written by #DavidFletcher:
import Data.Map(Map, fromListWith)
toCounter :: (Ord a, Integral i) => [a] -> Map a i
toCounter = fromListWith (+) . map (flip (,) 1)
we can however use toList to let it work with Foldables as well:
import Data.Foldable(toList)
import Data.Map(Map, fromListWith)
toCounter :: (Ord a, Foldable f, Integral i) => f a -> Map a i
toCounter = fromListWith (+) . map (flip (,) 1) . toList
I m a newbie to Haskell. I am pretty good with Imperative languages but not with functional. Haskell is my first as a functional language.
I am trying to figure out, how to get the index of the smallest element in the list where the minimum element is defined by me.
Let me explain by examples.
For example :
Function signature
minList :: x -> [x]
let x = 2
let list = [2,3,5,4,6,5,2,1,7,9,2]
minList x list --output 1 <- is index
This should return 1. Because the at list[1] is 3. It returns 1 because 3 is the smallest element after x (=2).
let x = 1
let list = [3,5,4,6,5,2,1,7,9,2]
minList x list -- output 9 <- is index
It should return 9 because at list[9] is 2 and 2 is the smallest element after 1. x = 1 which is defined by me.
What I have tried so far.
minListIndex :: (Ord a, Num a) => a -> [a] -> a
minListIndex x [] = 0
minListIndex x (y:ys)
| x > y = length ys
| otherwise = m
where m = minListIndex x ys
When I load the file I get this error
• Couldn't match expected type ‘a’ with actual type ‘Int’
‘a’ is a rigid type variable bound by
the type signature for:
minListIndex :: forall a. (Ord a, Num a) => a -> [a] -> a
at myFile.hs:36:17
• In the expression: 1 + length ys
In an equation for ‘minListIndex’:
minListIndex x (y : ys)
| x > y = 1 + length ys
| otherwise = 1 + m
where
m = minListIndex x ys
• Relevant bindings include
m :: a (bound at myFile.hs:41:19)
ys :: [a] (bound at myFile.hs:38:19)
y :: a (bound at myFile.hs:38:17)
x :: a (bound at myFile.hs:38:14)
minListIndex :: a -> [a] -> a (bound at myFile.hs:37:1)
When I modify the function like this
minListIndex :: (Ord a, Num a) => a -> [a] -> a
minListIndex x [] = 0
minListIndex x (y:ys)
| x > y = 2 -- <- modified...
| otherwise = 3 -- <- modifiedd
where m = minListIndex x ys
I load the file again then it compiles and runs but ofc the output is not desired.
What is the problem with
| x > y = length ys
| otherwise = m
?
In short: Basically, I want to find the index of the smallest element but higher than the x which is defined by me in parameter/function signature.
Thanks for the help in advance!
minListIndex :: (Ord a, Num a) => a -> [a] -> a
The problem is that you are trying to return result of generic type a but it is actually index in a list.
Suppose you are trying to evaluate your function for a list of doubles. In this case compiler should instantiate function's type to Double -> [Double] -> Double which is nonsense.
Actually compiler notices that you are returning something that is derived from list's length and warns you that it is not possible to match generic type a with concrete Int.
length ys returns Int, so you can try this instead:
minListIndex :: Ord a => a -> [a] -> Int
Regarding your original problem, seems that you can't solve it with plain recursion. Consider defining helper recursive function with accumulator. In your case it can be a pair (min_value_so_far, its_index).
First off, I'd separate the index type from the list element type altogether. There's no apparent reason for them to be the same. I will use the BangPatterns extension to avoid a space leak without too much notation; enable that by adding {-# language BangPatterns #-} to the very top of the file. I will also import Data.Word to get access to the Word64 type.
There are two stages: first, find the index of the given element (if it's present) and the rest of the list beyond that point. Then, find the index of the minimum of the tail.
-- Find the 0-based index of the first occurrence
-- of the given element in the list, and
-- the rest of the list after that element.
findGiven :: Eq a => a -> [a] -> Maybe (Word64, [a])
findGiven given = go 0 where
go !_k [] = Nothing --not found
go !k (x:xs)
| given == xs = Just (k, xs)
| otherwise = go (k+1) xs
-- Find the minimum (and its index) of the elements of the
-- list greater than the given one.
findMinWithIndexOver :: Ord a => a -> [a] -> Maybe (Word64, a)
findMinWithIndexOver given = go 0 Nothing where
go !_k acc [] = acc
go !k acc (x : xs)
| x <= given = go (k + 1) acc xs
| otherwise
= case acc of
Nothing -> go (k + 1) (Just (k, x)) xs
Just (ix_min, curr_min)
| x < ix_min = go (k + 1) (Just (k, x)) xs
| otherwise = go (k + 1) acc xs
You can now put these functions together to construct the one you seek. If you want a general Num result rather than a Word64 one, you can use fromIntegral at the very end. Why use Word64? Unlike Int or Word, it's (practically) guaranteed not to overflow in any reasonable amount of time. It's likely substantially faster than using something like Integer or Natural directly.
It is not clear for me what do you want exactly. Based on examples I guess it is: find the index of the smallest element higher than x which appears after x. In that case, This solution is plain Prelude. No imports
minList :: Ord a => a -> [a] -> Int
minList x l = snd . minimum . filter (\a -> x < fst a) . dropWhile (\a -> x /= fst a) $ zip l [0..]
The logic is:
create the list of pairs, [(elem, index)] using zip l [0..]
drop elements until you find the input x using dropWhile (\a -> x /= fst a)
discards elements less than x using filter (\a -> x < fst a)
find the minimum of the resulting list. Tuples are ordered using lexicographic order so it fits your problem
take the index using snd
Your function can be constructed out of ready-made parts as
import Data.Maybe (listToMaybe)
import Data.List (sortBy)
import Data.Ord (comparing)
foo :: (Ord a, Enum b) => a -> [a] -> Maybe b
foo x = fmap fst . listToMaybe . take 1
. dropWhile ((<= x) . snd)
. sortBy (comparing snd)
. dropWhile ((/= x) . snd)
. zip [toEnum 0..]
This Maybe finds the index of the next smallest element in the list above the given element, situated after the given element, in the input list. As you've requested.
You can use any Enum type of your choosing as the index.
Now you can implement this higher-level executable specs as direct recursion, using an efficient Map data structure to hold your sorted elements above x seen so far to find the next smallest, etc.
Correctness first, efficiency later!
Efficiency update: dropping after the sort drops them sorted, so there's a wasted effort there; indeed it should be replaced with the filtering (as seen in the answer by Luis Morillo) before the sort. And if our element type is in Integral (so it is a properly discrete type, unlike just an Enum, thanks to #dfeuer for pointing this out!), there's one more opportunity for an opportunistic optimization: if we hit on a succ minimal element by pure chance, there's no further chance of improvement, and so we should bail out at that point right there:
bar :: (Integral a, Enum b) => a -> [a] -> Maybe b
bar x = fmap fst . either Just (listToMaybe . take 1
. sortBy (comparing snd))
. findOrFilter ((== succ x).snd) ((> x).snd)
. dropWhile ((/= x) . snd)
. zip [toEnum 0..]
findOrFilter :: (a -> Bool) -> (a -> Bool) -> [a] -> Either a [a]
findOrFilter t p = go
where go [] = Right []
go (x:xs) | t x = Left x
| otherwise = fmap ([x | p x] ++) $ go xs
Testing:
> foo 5 [2,3,5,4,6,5,2,1,7,9,2] :: Maybe Int
Just 4
> foo 2 [2,3,5,4,6,5,2,1,7,9,2] :: Maybe Int
Just 1
> foo 1 [3,5,4,6,5,2,1,7,9,2] :: Maybe Int
Just 9
First, I am completely new to Haskell, so sorry for the question in advance, as it might look kind of simple, but still I get this error message:
Couldn't match expected type `[a]' with actual type `a'
`a' is a rigid type variable bound by
the type signature for middle :: [a] -> a
at myFile.lhs:18:12
Relevant bindings include
xs :: [a] (bound at myFile.lhs:20:12)
x :: a (bound at myFile.lhs:20:10)
middle :: [a] -> a
(bound at myFile.lhs:19:2)
In the first argument of `(!!)', namely `x'
In the first argument of `div', namely `x !! length xs'
Failed, modules loaded: none.
While trying to load:
>middle :: [a] -> a
>middle [] = []
>middle (x:xs) = if (l `mod` 2 == 0) then xs !! (l`div` 2) - 1 else x !! l `div` 2
where l = length xs
If something is vague or unclear, please comment.
EDIT
Because of the use of div I get:
Error: No instance for (Integral a) arising from a use of `div'
Possible fix:
add (Integral a) to the context of
the type signature for middle :: [a] -> a
In the expression: xs !! l `div` 2
In the expression:
if (l `mod` 2 == 0) then xs !! (l `div` 2) - 1 else xs !! l `div` 2
In an equation for `middle':
middle (x : xs)
= if (l `mod` 2 == 0) then
xs !! (l `div` 2) - 1
else
xs !! l `div` 2
where
l = length xs
Note that x is just an element, not a list. So, using x !! anything is a type error. Did you mean xs !! anything instead?
Further,
middle [] = []
is wrong since you must return an element, not a list. Since there is no middle element, we can only return bottom, e.g.
middle [] = error "middle: empty list"
The above makes the function a partial one, i.e. if in a larger program you call the function with an empty list, the program will crash.
If you want to forbid that, you can change the type to Maybe:
middle :: [a] -> Maybe a
middle [] = Nothing
middle (x:xs) = Just (.....)