Other way around - the compiler knows that MonkeyFun returns a string list ("but given a..."), but you need a function that returns a single string ("expecting a ...") to make it work. List.map will always return a list, the argument to List.map is a function that just operates on the elements. The way you have it now, the last line will return a string list list (that is, list<list<string>>). Does it make sense?

(By the way, an easy way to help understand/debug this is to change the last part of the last line to

1
2
      let r = List.map MonkeyFun m 
      r

and then hover over the 'r'.)

By on 9/18/2008 6:43 PM ()

The way you have it now, the last line will return a string list list (that is, list<list<string>>).

That's exactly what I want it to return. That's what I expect MonkeyFun to return. I would expect List.map with a list of MonkeyTuple passed the function MonkeyFun to match on type Monkey (the first match) for each item in the list and finally return list<list<string>>. But apparently I can't do that. Why?

By on 9/19/2008 7:27 AM ()

It's because the other branch of the match returns "TurnMonkeyIntoList m" which has type "list<string>". So maybe you want to wrap that in another list.

By on 9/19/2008 9:48 AM ()

It's because the other branch of the match returns "TurnMonkeyIntoList m" which has type "list<string>". So maybe you want to wrap that in another list.

Here's how it looks to me:
a call to MonkeyFun with list<MonkeyTuple> would hit the second branch in the function. That branch calls List.map passing MonkeyFun as the (recursive) function. Each item in the original list would then change from a MonkeyTuple to a list<string> which would result in list<list<string>>.
Thus, I can't figure out what to change in the code. If I wrap the result of TurnMonkeyIntoList in another list, that merely adds another 'list' to the compiler error.

By on 9/19/2008 12:00 PM ()

Oops, you're right, I should try code before just firing off an answer. :)

Here is one possible 'solution' to make it typecheck:

1
2
3
4
5
6
7
8
9
10
11
12
13
type MonkeyTuple = (int * string)
type MonkeyUnion = 
  | Monkey of MonkeyTuple
  | Monkeys of MonkeyTuple list
let TurnMonkeyTupleIntoList (mt : MonkeyTuple) =
  let ((a:int), b) = mt
  [System.Convert.ToString(a); b]
let MonkeyFun mUnion =
  match mUnion with
  | Monkey(m) -> TurnMonkeyTupleIntoList m
  | Monkeys(m) -> let listOfLists = List.map TurnMonkeyTupleIntoList m
                  let r = List.concat listOfLists
                  r

The keys are the List.concat call (to turn a list of lists into a list) and the fact that List.map is called with the other function (MonkeyFun does not need to be recursive). Given the nonsense names, I an not clear if this does what you want or not, but it typechecks.

By on 9/19/2008 12:40 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper