Higher Order Function: "Cannot Invoke 'Map' with an Argument List of Type '((_) -> _)'"

Higher order function: Cannot invoke 'map' with an argument list of type '((_) - _)'

I would say that map is not for this kind of operation. It creates a new sequence based on an others sequences elements, but what you don't want to create a sequence, you just want to iterate through them and apply a function to them. In swift there is no higher order function that matches what you want, I hope they will put something in soon. So the best you can do is to use a for loop or write your own function which does what you want.

I would like to suggest to write your own functon (based on what scalas foreach is):

extension Array {

func foreach(function: T -> ()) {
for elem in self {
function(elem)
}
}
}

UPDATED with Swift 2.0

forEach added to the SequenceType, so it is available:

(cell.contentView.subviews as [UIView]).forEach { $0.removeFromSuperview() }

Swift compiler error: “Cannot invoke 'map' with an argument list of type '((_) - _)'”

Swift can't infer types from the context every time. If it can't infer types, you have to type them explicitly, in this case the return type:

let patterns = (0...5).map { verseNum -> String in

In this case I believe Swift should be able to infer the type so it might be a bug.

Cannot invoke 'methodName' with an argument list of type

You are passing an object of type T to getValueType. T is an unconstrained generic type, which means that at compile time it could be any type known in the scope. It has a definite type, but the compiler doesn't know what that type is. T is a placeholder for it.

When it encounters the line that invokes getValueType with an argument of type T it looks for a way to satisfy that. the error you see says that it didn't find a way to do that.

Here's a minimal example:

func foo<U>(f:U) {
bar(b:f)
}

func bar(b:Int) {
}

This fails because bar accepts an Int, but foo could pass it any type.

There are two ways to fix this.

Method 1

Make bar generic:

func bar<V>(b:V) {
}

so if you call

foo(f:1)

The compiler replaces U with Int, creating:

func foo(f:Int) {
bar(b:f)
}

Now it needs a bar that accepts an Int, so it replaces V with Int to give

func bar(b:Int) {
}

Now the types are consistent so it can proceed.

Method 2

Constrain U:

protocol P {}

func foo<U:P>(f:U) {
bar(b:f)
}

This says that U is any type that conforms to the protocol P. So now we can define bar like this:

func bar(b:P) {
}

This defines a bar that accepts anything that conforms to protocol P.

Now whatever the placeholder U is replaced with, the compiler knows that it conforms to P, and it can always find a bar that accepts something that conforms to P. The compiler can proceed.

Swit map: error: cannot invoke 'map' with an argument list of type '((_) - _)'

The problem here is there error message. In general, when you see something like cannot invoke .. with ... it means that the compiler's type inference has just not worked.

In this case, you've run up against one of the limitations of inference within closures. Swift can infer the type of single-statement closures only, not multiple-statement ones. In your first example:

arr.map() {
x in
return x + 2
}

There's actually only one statement: return x + 2. However, in the second:

arr.map() {
x in
var y = x + 2
return y
}

There's an assignment statement (var y = x + 2), and then the return. So the error is a little misleading: it doesn't mean you "can't invoke map() with this type of argument", what it means to say is "I can't figure out what type x or y is".

By the way, in single-statement closures, there are two other things that can be inferred. The return statement:

arr.map() {
x in
x + 2
}

And the variable name itself:

arr.map() { $0 + 2 }

It all produces the same compiled code, though. So it's really a matter of taste which one you choose. (For instance, while I think the inferred return looks clean and easier to read, I don't like the $0, so I generally always put x in or something, even for very short closures. It's up to you, though, obviously.)

One final thing: since this is all really just syntax stuff, it's worth noting that the () isn't needed either:

arr.map { x in x + 2 }

As @MartinR pointed out, the compiler can infer some types from outer context as well:

let b: [Int] = arr.map { x in
var y = x + 2
return y
}

Which is worth bearing in mind. (it seems that the "one-statement" rule only applies when there's no other type info available)

Cannot invoke 'map' with an argument list of type '([AnyObject],(_) - _)'

Don't use forced cast, and call map on the array, as the function was moved in Swift 2

return (self.object as? [AnyObject])?.map{ JSON($0) }

Swift 3.1 error: cannot invoke 'stride' with an argument list of type

This is kind of tricky! :)

Int apparently declares its own stride methods (that's why the compiler shows you that partially matching overloads exist), but somehow I can't access them (compiler says that they are marked unavailable). Since you are in an Int extension, calling stride in this context is equivalent to self.stride. And the stride methods that Int has does not have the arguments from:to:by:, so it does not compile.

You want to specifically refer to the stride method that's global. Just specify the module in which the method is defined, i.e. Swift:

extension Int{

func hello(to end: Int, by step: Int, task: (Int) -> Void ){

for i in Swift.stride(from: 4, to: 8, by: 2) {

task(i)
}
}
}

Swift error cannot invoke '+' with an argument list of type '($T28, $T32)'

if you try to create an Integer Array:

let array:[Int] = [0, 1, 2, 3, 4, 5] 

I had the same issue. I guess to compiler did not recognize the type of your array values.

If you use:

let sum = Int(array[0]) + Int(array[1]) + Int(array[2]) + Int(array[3]) + Int(array[4]) + Int(array[5])

it works as expected.

Cannot invoke an object which is possibly 'undefined'.ts(2722)

Now how can as per the erro mentioned in question, object be possibly undefined? [sic]

The use of Partial<T> around export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps> causes onClick to be optional. When we use Partial<T>, all the properties receive the ? and thus become optional, which means that all of them can be undefined.

There are two approached to a fix: one is to keep ButtonProps the same with onClick as optional, and to check that onClick is defined before calling it (fix 1); the other is to change ButtonProps to make onClick required (fix 2 and 3).

Fix 1: onClick remains optional

Use the ButtonProps that you already have, and then check that onClick is defined before calling it. This is what antd does in the code you linked in the comments.

const Button = (props: ButtonProps) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
if (props.onClick) props.onClick(e); // works
};
};

Fix 2: onClick becomes required

Change ButtonProps by not applying the Partial to the NativeButtonProps:

type ButtonProps1 = Partial<AnchorButtonProps> & NativeButtonProps;

const Button1 = (props: ButtonProps1) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
props.onClick(e); // works
};
};

Fix 3: onClick becomes required too

Define a RequireKeys type, which lets you to specify the keys that are not optional.

type RequireKeys<T, TNames extends keyof T> = T &
{ [P in keyof T]-?: P extends TNames ? T[P] : never };

type ButtonProps2 = RequireKeys<ButtonProps, "onClick">;

const Button2 = (props: ButtonProps2) => {
const handleClick: React.MouseEventHandler<
HTMLButtonElement | HTMLAnchorElement
> = e => {
props.onClick(e); // works
};
};

The answers to Mapped Types: removing optional modifier have more information about how I defined RequireKeys<T>.

Using higher-order Haskell types in C#

I'll elaborate here on my comment on FUZxxl's post.

The examples you posted are all possible using FFI. Once you export your functions using FFI you can as you've already figured out compile the program into a DLL.

.NET was designed with the intention of being able to interface easily with C, C++, COM, etc. This means that once you're able to compile your functions to a DLL, you can call it (relatively) easy from .NET. As I've mentioned before in my other post that you've linked to, keep in mind which calling convention you specify when exporting your functions. The standard in .NET is stdcall, while (most) examples of Haskell FFI export using ccall.

So far the only limitation I've found on what can be exported by FFI is polymorphic types, or types that are not fully applied. e.g. anything other than kind * (You can't export Maybe but you can export Maybe Int for instance).

I've written a tool Hs2lib that would cover and export automatically any of the functions you have in your example. It also has the option of generating unsafe C# code which makes it pretty much "plug and play". The reason I've choosen unsafe code is because it's easier to handle pointers with, which in turn makes it easier to do the marshalling for datastructures.

To be complete I'll detail how the tool handles your examples and how I plan on handling polymorphic types.

  • Higher order functions

When exporting higher order functions, the function needs to be slightly changed. The higher-order arguments need to become elements of FunPtr. Basically They're treated as explicit function pointers (or delegates in c#), which is how higher orderedness is typically done in imperative languages.

Assuming we convert Int into CInt the type of double is transformed from

(Int -> Int) -> Int -> Int

into

FunPtr (CInt -> CInt) -> CInt -> IO CInt

These types are generated for a wrapper function (doubleA in this case) which is exported instead of double itself. The wrapper functions maps between the exported values and the expected input values for the original function. The IO is needed because constructing a FunPtr is not a pure operation.

One thing to remember is that the only way to construct or dereference a FunPtr is by statically creating imports which instruct GHC to create stubs for this.

foreign import stdcall "wrapper" mkFunPtr  :: (Cint -> CInt) -> IO (FunPtr (CInt -> CInt))
foreign import stdcall "dynamic" dynFunPtr :: FunPtr (CInt -> CInt) -> CInt -> CInt

The "wrapper" function allows us to create a FunPtr and the "dynamic" FunPtr allows one to deference one.

In C# we declare the input as a IntPtr and then use the Marshaller helper function Marshal.GetDelegateForFunctionPointer to create a function pointer that we can call, or the inverse function to create a IntPtr from a function pointer.

Also remember that the calling convention of the function being passed as an argument to the FunPtr must match the calling convention of the function to which the argument is being passed to. In other words, passing &foo to bar requires foo and bar to have the same calling convention.

  • User datatypes

Exporting a user datatype is actually quite straight forward. For every datatype that needs to be exported a Storable instance has to be created for this type. This instances specifies the marshalling information that GHC needs in order to be able to export/import this type. Among other things you would need to define the size and alignment of the type, along with how to read/write to a pointer the values of the type. I partially use Hsc2hs for this task (hence the C macros in the file).

newtypes or datatypes with just one constructor is easy. These become a flat struct since there's only one possible alternative when constructing/destructing these types. Types with multiple constructors become a union (a struct with Layout attribute set to Explicit in C#). However we also need to include an enum to identify which construct is being used.

in general, the datatype Single defined as

data Single = Single  { sint   ::  Int
, schar :: Char
}

creates the following Storable instance

instance Storable Single where
sizeOf _ = 8
alignment _ = #alignment Single_t

poke ptr (Single a1 a2) = do
a1x <- toNative a1 :: IO CInt
(#poke Single_t, sint) ptr a1x
a2x <- toNative a2 :: IO CWchar
(#poke Single_t, schar) ptr a2x

peek ptr = do
a1' <- (#peek Single_t, sint) ptr :: IO CInt
a2' <- (#peek Single_t, schar) ptr :: IO CWchar
x1 <- fromNative a1' :: IO Int
x2 <- fromNative a2' :: IO Char
return $ Single x1 x2

and the C struct

typedef struct Single Single_t;

struct Single {
int sint;
wchar_t schar;
} ;

The function foo :: Int -> Single would be exported as foo :: CInt -> Ptr Single
While a datatype with multiple constructor

data Multi  = Demi  {  mints    ::  [Int]
, mstring :: String
}
| Semi { semi :: [Single]
}

generates the following C code:

enum ListMulti {cMultiDemi, cMultiSemi};

typedef struct Multi Multi_t;
typedef struct Demi Demi_t;
typedef struct Semi Semi_t;

struct Multi {
enum ListMulti tag;
union MultiUnion* elt;
} ;

struct Demi {
int* mints;
int mints_Size;
wchar_t* mstring;
} ;

struct Semi {
Single_t** semi;
int semi_Size;
} ;

union MultiUnion {
struct Demi var_Demi;
struct Semi var_Semi;
} ;

The Storable instance is relatively straight forward and should follow easier from the C struct definition.

  • Applied types

My dependency tracer would for emit for for the type Maybe Int the dependency on both the type Int and Maybe. This means, that when generating the Storable instance for Maybe Int the head looks like

instance Storable Int => Storable (Maybe Int) where

That is, aslong as there's a Storable instance for the arguments of the application the type itself can also be exported.

Since Maybe a is defined as having a polymorphic argument Just a, when creating the structs, some type information is lost. The structs would contain a void* argument, which you have to manually convert to the right type. The alternative was too cumbersome in my opinion, which was to create specialized structs aswell. E.g. struct MaybeInt. But the amount of specialized structures that could be generated from a normal module can quickly explode this way. (might add this as a flag later on).

To ease this loss of information my tool will export any Haddock documentation found for the function as comments in the generated includes. It will also place the original Haskell type signature in the comment as well. An IDE would then present these as part of its Intellisense (code compeletion).

As with all of these examples I've ommited the code for the .NET side of things, If you're interested in that you can just view the output of Hs2lib.

There are a few other types that need special treatment. In particular Lists and Tuples.

  1. Lists need to get passed the size of the array from which to marshall from, since we're interfacing with unmanaged languages where the size of the arrays are not implicitly known. Conversly when we return a list, we also need to return the size of the list.
  2. Tuples are special build in types, In order to export them, we have to first map them to a "normal" datatype, and export those. In the tool this is done up untill 8-tuples.

    • Polymorphic types

The problem with polymorphic types e.g. map :: (a -> b) -> [a] -> [b] is that the size of a and b are not know. That is, there's no way to reserve space for the arguments and return value since we don't know what they are. I plan to support this by allowing you to specify possible values for a and b and create specialized wrapper function for these types. On the other size, in the imperative language I would use overloading to present the types you've chosen to the user.

As for classes, Haskell's open world assumption is usually a problem (e.g. an instance can be added any time). However at the time of compilation only a statically known list of instances is available. I intend to offer an option that would automatically export as much specialized instances as possible using these list. e.g. export (+) exports a specialized function for all known Num instances at compile time (e.g. Int, Double, etc).

The tool is also rather trusting. Since I can't really inspect the code for purity, I always trust that the programmer is honest. E.g. you don't pass a function that has side-effects to a function that expects a pure function. Be honest and mark the higher-ordered argument as being impure to avoid problems.

I hope this helps, and I hope this wasn't too long.

Update : There's somewhat of a big gotcha that I've recently discovered. We have to remember that the String type in .NET is immutable. So when the marshaller sends it to out Haskell code, the CWString we get there is a copy of the original. We have to free this. When GC is performed in C# it won't affect the the CWString, which is a copy.

The problem however is that when we free it in the Haskell code we can't use freeCWString. The pointer was not allocated with C (msvcrt.dll)'s alloc. There are three ways (that I know of) to solve this.

  • use char* in your C# code instead of String when calling a Haskell function. You then have the pointer to free when you call returns, or initialize the function using fixed.
  • import CoTaskMemFree in Haskell and free the pointer in Haskell
  • use StringBuilder instead of String. I'm not entirely sure about this one, but the idea is that since StringBuilder is implemented as a native pointer, the Marshaller just passes this pointer to your Haskell code (which can also update it btw). When GC is performed after the call returns, the StringBuilder should be freed.


Related Topics



Leave a reply



Submit