According to the "https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Maps/Pin.cs". There are two event MarkerClicked and InfoWindowClicked of Pin Class(Clicked has been obsoleted). No ref can be found and try to access the event with the helper With unsuccessfully. Please feel free to comment.
let jpnPins =
jpnDatas
|> List.map (fun (_, a, _, _, b, c) -> View.Pin(Position(b, c), label = a, pinType = PinType.Place)).With(Clicked=(fun () -> dispatch PinClicked))
|> Some
Related
I am pretty new to Haskell and I am trying to write a function neighbours :: Int -> Metric a -> Point a -> [Point a] -> [Point a] such that neighbours k d p xs returns a list of the k nearest neighbours, in distance order, according to metric d to point p in the list xs of points. My code is
type Point a = (a, a)
type Metric a = Point a -> Point a -> Double
type Tuple a = (Double, Point a)
create:: Metric a -> Point a -> [Point a] -> [Tuple a] -> [Tuple a]
create d p (x:xs) ys | length xs == 0 = sort(((d p x), x) : ys)
| otherwise = create d p xs (((d p x), x) : ys)
takeP:: Tuple a -> Point a
takeP (_,p) = p
pList:: [Tuple a] ->[Point a]-> [Point a]
pList (x:xs) ys | length xs == 0 = reverse (takeP x : ys)
| otherwise = pList xs (takeP x : ys)
neighbours :: Int -> Metric a -> Point a -> [Point a] -> [Point a]--
neighbours k d p xs = take k (pList (create d p xs []) [])
But I am getting an error on sort which is:
* No instance for (Ord a) arising from a use of `sort'
Possible fix:
add (Ord a) to the context of
the type signature for:
create :: forall a.
Metric a -> Point a -> [Point a] -> [Tuple a] -> [Tuple a]
* In the expression: sort (((d p x), x) : ys)
In an equation for `create':
create d p (x : xs) ys
| length xs == 0 = sort (((d p x), x) : ys)
| otherwise = create d p xs (((d p x), x) : ys)
I used type Point a = (Int, Int) at first and it was working fine but in the specification it is required that Point is type Point a = (a, a) which caused my error. The other problem is that I cannot change the function types so I can't just add (Ord a) as proposed.
Is there a way to sort the Tuples' list by the first variable without encountering errors?
In your create function, you make use of sort :: Ord a => [a] -> [a]:
… = sort (((d p x), x) : ys)
this thus means that type of objects that we are sorting, in this case Tuple a, needs to be an instance of the Ord typeclass. A 2-tuple is an instance of the Ord typeclass, if both the type of the items are instances of Ord as well, so in this case Double and Point a. Since Point a is also a 2-tuple, but of two as, this thus means that Tuple a is an instance of Ord, if a is an instance of Ord. You thus should add a type constraint:
create :: Ord a => Metric a -> Point a -> [Point a] -> [Tuple a] -> [Tuple a]
create d p (x:xs) ys | length xs == 0 = sort(((d p x), x) : ys)
| otherwise = create d p xs (((d p x), x) : ys)
The create function makes use of some anti-patterns like using length, which takes linear time. You can in fact rewrite this to sorting a mapping:
create :: Ord a => Metric a -> Point a -> [Point a] -> [Tuple a]
create d p = sort . map f
where f x = (d p x, x)
This removes the ys parameter, which here only seems to be used as a accumulator.
If you wish to only sort on the first item of the 2-tuple, you can make use of sortOn :: Ord b => (a -> b) -> [a] -> [a]:
create :: Metric a -> Point a -> [Point a] -> [Tuple a]
create d p = sortOn fst . map f
where f x = (d p x, x)
fun merge_sort (_, nil) = nil
| merge_sort (_, [a]) = [a]
| merge_sort (f, L) =
let
fun halve nil = (nil,nil)
| halve [a] = ([a], nil)
| halve (a :: b :: rest) =
let
val (x , y) = halve rest
in
(a :: x, b :: y)
end
fun merge (f, nil, x) = x
| merge (f, x, nil) = x
| merge (f, a::b, x::y) =
if f(a, b) then a :: merge (f, b, x::y)
else x :: merge (f, a::b, y);
val (x, y) = halve L
in
merge(f, merge_sort(f, x), merge_sort(f,y))
end;
merge_sort (op <) [2,1,3,2,4,3,45];
This is a SML function that I have been working on. It is meant to take a function call as shown in the bottom and merge sort. Must be one function. I am struggling understanding the pattern matching and how to fully make this function work.
I get this error code when I compile and run it.
$sml < main.sml
Standard ML of New Jersey v110.78 [built: Thu Aug 31 03:45:42 2017]
- val merge_sort = fn : ('a * 'a list -> bool) * 'a list -> 'a list
stdIn:23.1-23.35 Error: operator and operand don't agree [tycon mismatch]
operator domain: ('Z * 'Z list -> bool) * 'Z list
operand: [< ty] * [< ty] -> bool
in expression:
merge_sort <
-
I don't entirely know what I am doing wrong
Using the convention of naming lists with a plural "s" and using the same base name for the head and tail in patterns makes the problem stick out immediately:
merge (f, x::xs, y::ys) =
if f(x, xs) then x :: merge (f, xs, y::ys)
else y :: merge (f, x::xs, ys);
where f(x, xs) should of course be f(x, y).
This convention is conventional because it's useful. Don't leave home without it.
You have a typo; this:
if f(a, b) then a :: merge (f, b, x::y)
else x :: merge (f, a::b, y);
should be this:
if f (a, x) then a :: merge (f, b, x::y)
else x :: merge (f, a::b, y)
(calling f on (a, x) rather than on (a, b)).
Since b and x have different types ('Z list and 'Z, respectively), the consequence of this typo is that f is inferred to have the wrong type ('Z * 'Z list -> bool rather than 'Z * 'Z -> bool), so the whole merge_sort function is inferred to have the wrong type scheme (('a * 'a list -> bool) * 'a list -> 'a list instead of ('a * 'a -> bool) * 'a list -> 'a list).
Some explicit type annotations (e.g. writing f : 'a * 'a -> bool in one place) might make it easier for the compiler to help you see where you're deviating from the types you intended; but, admittedly, if you don't already know where you're deviating, then it can be hard to figure out where to add annotations so the compiler can help you find where you're deviating.
So I know how to write a code to see if my list is sorted from smallest to biggest
isSorted :: (Ord a) => [a] -> Bool
isSorted [] = True
isSorted [x] = True
isSorted (x:y:xs) = x <= y && isSorted (y:xs)
But I would like to write a code that tells me if my list is sorted by the given comparison operator
for example
I wanna put in
sorted (<=) [1,2,2,4,5] == True
sorted (<) [1,2,2,4,5] == False
sorted (==) [1,2,2,2,3] == False
What would I have to do?
I would like to write a code that tells me if my list is sorted by the given comparison operator for example I wanna put in
isSorted function can be enhanced to receive a function, which compares two elements and that function can be called instead of <= in your example:
isSorted :: (a -> a -> Bool) -> [a] -> Bool
isSorted _ [] = True
isSorted _ [x] = True
isSorted comparator (x:y:xs) = comparator x y && isSorted comparator (y:xs)
So the function is going to be called as:
isSorted (<) [1, 2, 3]
isSorted (>=) [3, 2, 1]
Calling it with (==) will just compare if the elements are the same in the list.
The idea can be to parameterize the comparison. Now you use <=, but we can replace it with an f, we pass as a parameter:
isSorted :: (a -> a -> Bool) -> [a] -> Bool
isSorted _ [] = True
isSorted _ [x] = True
isSorted f (x:y:xs) = f x y && isSorted f (y:xs)
We can however improve the following code by using zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] and and :: [Bool] -> Bool:
isSorted :: (a -> a -> Bool) -> [a] -> Bool
isSorted _ [] = True
isSorted f xs#(_:xs2) = and(zipWith f xs xs2)
The isSorted thus takes a predicate that works with two as, and we check if the predicate holds for every item, and its next item. You can thus write more advanced predicates that do not necessary encapsulate an order relation.
I'm trying to write a function that will Nothing a Just Int tuple if any two values in the tuple are the same. For a tuple of five values, here's what I've got. Clearly, there's room for improvement:
nothingIfMatch :: Maybe (Int, Int, Int, Int, Int) -> Maybe (Int, Int, Int, Int, Int)
nothingIfMatch Nothing = Nothing
nothingIfMatch (Just (a, b, c, d, e))
| a == b = Nothing
| a == c = Nothing
| a == d = Nothing
| a == e = Nothing
| b == c = Nothing
| b == d = Nothing
| b == e = Nothing
| c == d = Nothing
| c == e = Nothing
| d == e = Nothing
| otherwise = Just (a, b, c, d, e)
Considering there are "n choose 2" possible intersections for an n-tuple, in this case, there are only 10 options. But imagine this were an 8-tuple, with 28 possibilities, or a 10-tuple, with 45.
There has to be a more idiomatic way to do this, probably relying on non-determinism features.
How should this be done?
We can first produce a list of Ints and then perform all equality checks:
import Data.List(tails)
twoEqual :: Eq a => [a] -> Bool
twoEqual xs = any (uncurry elem) [(h, t) | (h:t) <- tails xs]
Here we first generate for every element in the list a tuple containing the element and the rest of the list. Then we perform elem functions: we call elem on the item and the rest of the list and in case any of these checks holds, then we return True, False otherwise.
So now we can construct a list from this tuple and then use a guard to perform the checks:
nothingIfMatch :: Eq a => Maybe (a, a, a, a, a) -> Maybe (a, a, a, a, a)
nothingIfMatch = (>>= f)
where f r#(a, b, c, d, e) | twoEqual [a, b, c, d, e] = Nothing
| otherwise = Just r
We can easily add one extra element to the tuple and add it to the list in the twoEqual call. Here we still perform O(n2). We can do it in O(n log n) if we can order the elements first, or we can even do it in O(n) in case the elements are hashable and no hash collisions occur.
For example:
-- O(n log n) if the elements can be ordered
import Data.List(sort, tails)
twoEqual :: Ord a => [a] -> Bool
twoEqual xs = or [h1 == h2 | (h1:h2:_) <- tails (sort xs)]
Or in case the elements can be hashed:
-- O(n) in case the elements are hashable and no hash collisions
import Data.Hashable(Hashable)
import Data.HashSet(fromList, member)
twoEqual :: (Hashable a, Ord a) => [a] -> Bool
twoEqual xs = any (flip member hs) xs
where hs = fromList xs
I wanted an alternative to filter that would, instead of discarding the false cases, keep them in a separate place. I came up with the below, but unfortunately it reverses the list.
Obviously I could append x to ys or zs instead of cons, but this would dramatically increase complexity.
Is there a way to keep it in order without increasing complexity?
splitBy :: (a -> Bool) -> [a] -> ([a],[a])
splitBy f xs = splitBy' f xs ([],[])
where
splitBy' :: (a -> Bool) -> [a] -> ([a],[a]) -> ([a],[a])
splitBy' _ [] result = result
splitBy' f (x:xs) (ys,zs) = if f x then splitBy' f xs (x:ys,zs)
else splitBy' f xs (ys,x:zs)
As others have said, the function is called partition, and it works something like this
partition :: (a -> Bool) -> [a] -> ([a], [a])
partition f = foldr (\x ~(yes,no) ->
if f x
then (x:yes,no)
else (yes,x:no))
([], [])
except that the real version adds an explicit xs parameter, perhaps to help fusion rules work properly. If that funky lazy pattern match makes you nervous, you can write it like this instead:
partition f = foldr (\x r ->
if f x
then (x:fst r,snd r)
else (fst r,x:snd r))
([], [])
If the foldr seems mysterious to you, you can do it like this:
partition f [] = ([], [])
partition f (x:xs)
| f x = (x:fst r, snd r)
| otherwise = (fst r, x:snd r)
where r = partition f xs