5 people like it.

F# Koans

An online version of the F# Koans for use with tryfsharp

   1: 
   2: 
   3: 
   4: 
   5: 
   6: 
   7: 
   8: 
   9: 
  10: 
  11: 
  12: 
  13: 
  14: 
  15: 
  16: 
  17: 
  18: 
  19: 
  20: 
  21: 
  22: 
  23: 
  24: 
  25: 
  26: 
  27: 
  28: 
  29: 
  30: 
  31: 
  32: 
  33: 
  34: 
  35: 
  36: 
  37: 
  38: 
  39: 
  40: 
  41: 
  42: 
  43: 
  44: 
  45: 
  46: 
  47: 
  48: 
  49: 
  50: 
  51: 
  52: 
  53: 
  54: 
  55: 
  56: 
  57: 
  58: 
  59: 
  60: 
  61: 
  62: 
  63: 
  64: 
  65: 
  66: 
  67: 
  68: 
  69: 
  70: 
  71: 
  72: 
  73: 
  74: 
  75: 
  76: 
  77: 
  78: 
  79: 
  80: 
  81: 
  82: 
  83: 
  84: 
  85: 
  86: 
  87: 
  88: 
  89: 
  90: 
  91: 
  92: 
  93: 
  94: 
  95: 
  96: 
  97: 
  98: 
  99: 
 100: 
 101: 
 102: 
 103: 
 104: 
 105: 
 106: 
 107: 
 108: 
 109: 
 110: 
 111: 
 112: 
 113: 
 114: 
 115: 
 116: 
 117: 
 118: 
 119: 
 120: 
 121: 
 122: 
 123: 
 124: 
 125: 
 126: 
 127: 
 128: 
 129: 
 130: 
 131: 
 132: 
 133: 
 134: 
 135: 
 136: 
 137: 
 138: 
 139: 
 140: 
 141: 
 142: 
 143: 
 144: 
 145: 
 146: 
 147: 
 148: 
 149: 
 150: 
 151: 
 152: 
 153: 
 154: 
 155: 
 156: 
 157: 
 158: 
 159: 
 160: 
 161: 
 162: 
 163: 
 164: 
 165: 
 166: 
 167: 
 168: 
 169: 
 170: 
 171: 
 172: 
 173: 
 174: 
 175: 
 176: 
 177: 
 178: 
 179: 
 180: 
 181: 
 182: 
 183: 
 184: 
 185: 
 186: 
 187: 
 188: 
 189: 
 190: 
 191: 
 192: 
 193: 
 194: 
 195: 
 196: 
 197: 
 198: 
 199: 
 200: 
 201: 
 202: 
 203: 
 204: 
 205: 
 206: 
 207: 
 208: 
 209: 
 210: 
 211: 
 212: 
 213: 
 214: 
 215: 
 216: 
 217: 
 218: 
 219: 
 220: 
 221: 
 222: 
 223: 
 224: 
 225: 
 226: 
 227: 
 228: 
 229: 
 230: 
 231: 
 232: 
 233: 
 234: 
 235: 
 236: 
 237: 
 238: 
 239: 
 240: 
 241: 
 242: 
 243: 
 244: 
 245: 
 246: 
 247: 
 248: 
 249: 
 250: 
 251: 
 252: 
 253: 
 254: 
 255: 
 256: 
 257: 
 258: 
 259: 
 260: 
 261: 
 262: 
 263: 
 264: 
 265: 
 266: 
 267: 
 268: 
 269: 
 270: 
 271: 
 272: 
 273: 
 274: 
 275: 
 276: 
 277: 
 278: 
 279: 
 280: 
 281: 
 282: 
 283: 
 284: 
 285: 
 286: 
 287: 
 288: 
 289: 
 290: 
 291: 
 292: 
 293: 
 294: 
 295: 
 296: 
 297: 
 298: 
 299: 
 300: 
 301: 
 302: 
 303: 
 304: 
 305: 
 306: 
 307: 
 308: 
 309: 
 310: 
 311: 
 312: 
 313: 
 314: 
 315: 
 316: 
 317: 
 318: 
 319: 
 320: 
 321: 
 322: 
 323: 
 324: 
 325: 
 326: 
 327: 
 328: 
 329: 
 330: 
 331: 
 332: 
 333: 
 334: 
 335: 
 336: 
 337: 
 338: 
 339: 
 340: 
 341: 
 342: 
 343: 
 344: 
 345: 
 346: 
 347: 
 348: 
 349: 
 350: 
 351: 
 352: 
 353: 
 354: 
 355: 
 356: 
 357: 
 358: 
 359: 
 360: 
 361: 
 362: 
 363: 
 364: 
 365: 
 366: 
 367: 
 368: 
 369: 
 370: 
 371: 
 372: 
 373: 
 374: 
 375: 
 376: 
 377: 
 378: 
 379: 
 380: 
 381: 
 382: 
 383: 
 384: 
 385: 
 386: 
 387: 
 388: 
 389: 
 390: 
 391: 
 392: 
 393: 
 394: 
 395: 
 396: 
 397: 
 398: 
 399: 
 400: 
 401: 
 402: 
 403: 
 404: 
 405: 
 406: 
 407: 
 408: 
 409: 
 410: 
 411: 
 412: 
 413: 
 414: 
 415: 
 416: 
 417: 
 418: 
 419: 
 420: 
 421: 
 422: 
 423: 
 424: 
 425: 
 426: 
 427: 
 428: 
 429: 
 430: 
 431: 
 432: 
 433: 
 434: 
 435: 
 436: 
 437: 
 438: 
 439: 
 440: 
 441: 
 442: 
 443: 
 444: 
 445: 
 446: 
 447: 
 448: 
 449: 
 450: 
 451: 
 452: 
 453: 
 454: 
 455: 
 456: 
 457: 
 458: 
 459: 
 460: 
 461: 
 462: 
 463: 
 464: 
 465: 
 466: 
 467: 
 468: 
 469: 
 470: 
 471: 
 472: 
 473: 
 474: 
 475: 
 476: 
 477: 
 478: 
 479: 
 480: 
 481: 
 482: 
 483: 
 484: 
 485: 
 486: 
 487: 
 488: 
 489: 
 490: 
 491: 
 492: 
 493: 
 494: 
 495: 
 496: 
 497: 
 498: 
 499: 
 500: 
 501: 
 502: 
 503: 
 504: 
 505: 
 506: 
 507: 
 508: 
 509: 
 510: 
 511: 
 512: 
 513: 
 514: 
 515: 
 516: 
 517: 
 518: 
 519: 
 520: 
 521: 
 522: 
 523: 
 524: 
 525: 
 526: 
 527: 
 528: 
 529: 
 530: 
 531: 
 532: 
 533: 
 534: 
 535: 
 536: 
 537: 
 538: 
 539: 
 540: 
 541: 
 542: 
 543: 
 544: 
 545: 
 546: 
 547: 
 548: 
 549: 
 550: 
 551: 
 552: 
 553: 
 554: 
 555: 
 556: 
 557: 
 558: 
 559: 
 560: 
 561: 
 562: 
 563: 
 564: 
 565: 
 566: 
 567: 
 568: 
 569: 
 570: 
 571: 
 572: 
 573: 
 574: 
 575: 
 576: 
 577: 
 578: 
 579: 
 580: 
 581: 
 582: 
 583: 
 584: 
 585: 
 586: 
 587: 
 588: 
 589: 
 590: 
 591: 
 592: 
 593: 
 594: 
 595: 
 596: 
 597: 
 598: 
 599: 
 600: 
 601: 
 602: 
 603: 
 604: 
 605: 
 606: 
 607: 
 608: 
 609: 
 610: 
 611: 
 612: 
 613: 
 614: 
 615: 
 616: 
 617: 
 618: 
 619: 
 620: 
 621: 
 622: 
 623: 
 624: 
 625: 
 626: 
 627: 
 628: 
 629: 
 630: 
 631: 
 632: 
 633: 
 634: 
 635: 
 636: 
 637: 
 638: 
 639: 
 640: 
 641: 
 642: 
 643: 
 644: 
 645: 
 646: 
 647: 
 648: 
 649: 
 650: 
 651: 
 652: 
 653: 
 654: 
 655: 
 656: 
 657: 
 658: 
 659: 
 660: 
 661: 
 662: 
 663: 
 664: 
 665: 
 666: 
 667: 
 668: 
 669: 
 670: 
 671: 
 672: 
 673: 
 674: 
 675: 
 676: 
 677: 
 678: 
 679: 
 680: 
 681: 
 682: 
 683: 
 684: 
 685: 
 686: 
 687: 
 688: 
 689: 
 690: 
 691: 
 692: 
 693: 
 694: 
 695: 
 696: 
 697: 
 698: 
 699: 
 700: 
 701: 
 702: 
 703: 
 704: 
 705: 
 706: 
 707: 
 708: 
 709: 
 710: 
 711: 
 712: 
 713: 
 714: 
 715: 
 716: 
 717: 
 718: 
 719: 
 720: 
 721: 
 722: 
 723: 
 724: 
 725: 
 726: 
 727: 
 728: 
 729: 
 730: 
 731: 
 732: 
 733: 
 734: 
 735: 
 736: 
 737: 
 738: 
 739: 
 740: 
 741: 
 742: 
 743: 
 744: 
 745: 
 746: 
 747: 
 748: 
 749: 
 750: 
 751: 
 752: 
 753: 
 754: 
 755: 
 756: 
 757: 
 758: 
 759: 
 760: 
 761: 
 762: 
 763: 
 764: 
 765: 
 766: 
 767: 
 768: 
 769: 
 770: 
 771: 
 772: 
 773: 
 774: 
 775: 
 776: 
 777: 
 778: 
 779: 
 780: 
 781: 
 782: 
 783: 
 784: 
 785: 
 786: 
 787: 
 788: 
 789: 
 790: 
 791: 
 792: 
 793: 
 794: 
 795: 
 796: 
 797: 
 798: 
 799: 
 800: 
 801: 
 802: 
 803: 
 804: 
 805: 
 806: 
 807: 
 808: 
 809: 
 810: 
 811: 
 812: 
 813: 
 814: 
 815: 
 816: 
 817: 
 818: 
 819: 
 820: 
 821: 
 822: 
 823: 
 824: 
 825: 
 826: 
 827: 
 828: 
 829: 
 830: 
 831: 
 832: 
 833: 
 834: 
 835: 
 836: 
 837: 
 838: 
 839: 
 840: 
 841: 
 842: 
 843: 
 844: 
 845: 
 846: 
 847: 
 848: 
 849: 
 850: 
 851: 
 852: 
 853: 
 854: 
 855: 
 856: 
 857: 
 858: 
 859: 
 860: 
 861: 
 862: 
 863: 
 864: 
 865: 
 866: 
 867: 
 868: 
 869: 
 870: 
 871: 
 872: 
 873: 
 874: 
 875: 
 876: 
 877: 
 878: 
 879: 
 880: 
 881: 
 882: 
 883: 
 884: 
 885: 
 886: 
 887: 
 888: 
 889: 
 890: 
 891: 
 892: 
 893: 
 894: 
 895: 
 896: 
 897: 
 898: 
 899: 
 900: 
 901: 
 902: 
 903: 
 904: 
 905: 
 906: 
 907: 
 908: 
 909: 
 910: 
 911: 
 912: 
 913: 
 914: 
 915: 
 916: 
 917: 
 918: 
 919: 
 920: 
 921: 
 922: 
 923: 
 924: 
 925: 
 926: 
 927: 
 928: 
 929: 
 930: 
 931: 
 932: 
 933: 
 934: 
 935: 
 936: 
 937: 
 938: 
 939: 
 940: 
 941: 
 942: 
 943: 
 944: 
 945: 
 946: 
 947: 
 948: 
 949: 
 950: 
 951: 
 952: 
 953: 
 954: 
 955: 
 956: 
 957: 
 958: 
 959: 
 960: 
 961: 
 962: 
 963: 
 964: 
 965: 
 966: 
 967: 
 968: 
 969: 
 970: 
 971: 
 972: 
 973: 
 974: 
 975: 
 976: 
 977: 
 978: 
 979: 
 980: 
 981: 
 982: 
 983: 
 984: 
 985: 
 986: 
 987: 
 988: 
 989: 
 990: 
 991: 
 992: 
 993: 
 994: 
 995: 
 996: 
 997: 
 998: 
 999: 
1000: 
1001: 
1002: 
1003: 
1004: 
1005: 
1006: 
1007: 
1008: 
1009: 
1010: 
1011: 
1012: 
1013: 
1014: 
1015: 
1016: 
1017: 
1018: 
1019: 
1020: 
1021: 
1022: 
1023: 
1024: 
1025: 
1026: 
1027: 
1028: 
1029: 
1030: 
1031: 
1032: 
1033: 
1034: 
1035: 
1036: 
1037: 
1038: 
1039: 
1040: 
1041: 
1042: 
1043: 
1044: 
1045: 
1046: 
1047: 
1048: 
1049: 
1050: 
1051: 
1052: 
1053: 
1054: 
1055: 
1056: 
1057: 
1058: 
1059: 
1060: 
1061: 
1062: 
1063: 
1064: 
1065: 
1066: 
1067: 
1068: 
1069: 
1070: 
1071: 
1072: 
1073: 
1074: 
1075: 
1076: 
1077: 
1078: 
1079: 
1080: 
1081: 
1082: 
1083: 
1084: 
1085: 
1086: 
1087: 
1088: 
1089: 
1090: 
1091: 
1092: 
1093: 
1094: 
1095: 
1096: 
1097: 
1098: 
1099: 
1100: 
1101: 
1102: 
1103: 
1104: 
1105: 
1106: 
1107: 
1108: 
1109: 
1110: 
1111: 
1112: 
1113: 
1114: 
1115: 
1116: 
1117: 
1118: 
1119: 
1120: 
1121: 
1122: 
1123: 
1124: 
1125: 
1126: 
1127: 
1128: 
1129: 
1130: 
1131: 
1132: 
1133: 
1134: 
1135: 
1136: 
1137: 
1138: 
1139: 
1140: 
1141: 
1142: 
1143: 
1144: 
1145: 
1146: 
1147: 
1148: 
1149: 
1150: 
1151: 
1152: 
1153: 
1154: 
1155: 
1156: 
1157: 
1158: 
1159: 
1160: 
1161: 
1162: 
1163: 
1164: 
1165: 
1166: 
1167: 
1168: 
1169: 
1170: 
1171: 
1172: 
1173: 
1174: 
1175: 
1176: 
1177: 
1178: 
1179: 
1180: 
1181: 
1182: 
1183: 
1184: 
1185: 
1186: 
1187: 
1188: 
1189: 
1190: 
1191: 
1192: 
1193: 
1194: 
1195: 
1196: 
1197: 
1198: 
1199: 
1200: 
1201: 
1202: 
1203: 
1204: 
1205: 
1206: 
1207: 
1208: 
1209: 
1210: 
1211: 
1212: 
1213: 
1214: 
1215: 
1216: 
1217: 
1218: 
1219: 
1220: 
1221: 
1222: 
1223: 
1224: 
1225: 
1226: 
1227: 
1228: 
1229: 
1230: 
1231: 
1232: 
1233: 
1234: 
1235: 
1236: 
1237: 
1238: 
1239: 
1240: 
1241: 
1242: 
1243: 
1244: 
1245: 
1246: 
1247: 
1248: 
1249: 
1250: 
1251: 
1252: 
1253: 
1254: 
1255: 
1256: 
1257: 
1258: 
1259: 
1260: 
1261: 
1262: 
1263: 
1264: 
1265: 
1266: 
1267: 
1268: 
1269: 
1270: 
1271: 
1272: 
1273: 
1274: 
1275: 
1276: 
1277: 
1278: 
1279: 
1280: 
1281: 
1282: 
1283: 
1284: 
1285: 
1286: 
1287: 
1288: 
1289: 
1290: 
1291: 
1292: 
1293: 
1294: 
1295: 
1296: 
1297: 
1298: 
1299: 
1300: 
1301: 
1302: 
1303: 
1304: 
1305: 
1306: 
1307: 
1308: 
1309: 
1310: 
1311: 
1312: 
1313: 
1314: 
1315: 
1316: 
1317: 
1318: 
1319: 
1320: 
1321: 
1322: 
1323: 
1324: 
1325: 
1326: 
1327: 
1328: 
1329: 
1330: 
//---------------------------------------------------------------
// Overview
//
// Below is a set of exercises designed to get you familiar 
// with F#. By the time you're done, you'll have a basic 
// understanding of the syntax of F# and learn a little more
// about functional programming in general.
//
// Answering Problems
// 
// This is where the fun begins! Each dashed section contains an 
// example designed to teach you a lesson about the F# language. 
// If you highlight the code in an example and execute it (use 
// Ctrl+Enter or the run button) it will initially fail. Your
// job is to fill in the blanks to make it pass. With each
// passing section, you'll learn more about F#, and add another
// weapon to your F# programming arsenal.
//
// Start by highlighitng the section below and running it. Once
// you see it fail, replace the __ with 2 to make it pass.
//---------------------------------------------------------------

// ---- about asserts -------------------------------------------

let expected_value = 1 + 1
let actual_value = __

AssertEquality expected_value actual_value

//Easy, right? Try the next one.

//---------------------------------------------------------------
 
// ---- more about asserts --------------------------------------

AssertEquality "foo" __

//---------------------------------------------------------------

//---------------------------------------------------------------
// About Let
//
// The let keyword is one of the most fundamental parts of F#.
// You'll use it in almost every line of F# code you write, so
// let's get to know it well! (no pun intended)
//---------------------------------------------------------------

// ---- let binds a name to a value -----------------------------

let x = 50
        
AssertEquality x __
    
//---------------------------------------------------------------

// ---- let infers the type of values when it can ---------------

(* In F#, values created with let are inferred to have a type like
   "int" for integer values, "string" for text values, and "bool" 
   for true or false values. *)

let x = 50
let typeOfX = x.GetType()
AssertEquality typeOfX typeof<int>

let y = "a string"
let expectedType = y.GetType()
AssertEquality expectedType typeof<FILL_ME_IN>

//---------------------------------------------------------------

// ---- you can make the types explicit -------------------------

let (x:int) = 42
let typeOfX = x.GetType()

let y:string = "forty two"
let typeOfY = y.GetType()

AssertEquality typeOfX typeof<FILL_ME_IN>
AssertEquality typeOfY typeof<FILL_ME_IN>

(* You don't usually need to provide explicit type annotations 
   types for local varaibles, but type annotations can come in 
   handy in other contexts as you'll see later. *)

//---------------------------------------------------------------

// ---- floats and ints -----------------------------------------

(* Depending on your background, you may be surprised to learn that
    in F#, integers and floating point numbers are different types. 
    In other words, the following is true. *)
let x = 20
let typeOfX = x.GetType()

let y = 20.0
let typeOfY = y.GetType()

//you don't need to modify these
AssertEquality typeOfX typeof<int>
AssertEquality typeOfY typeof<float>

//If you're coming from another .NET language, float is F# slang for
//the double type.
   
//---------------------------------------------------------------

// ---- modifying the value of variables ------------------------

let mutable x = 100
x <- 200

AssertEquality x __

//---------------------------------------------------------------

// ---- you can't modify a value if it isn't mutable ------------

let x = 50

//What happens if you try to uncomment and run the following line of code?
//(look at the output in the output window)
//x <- 100

//NOTE: Although you can't modify immutable values, it is 
//      possible to reuse the name of a value in some cases 
//      using "shadowing".
let x = 100
 
AssertEquality x __

//---------------------------------------------------------------

//---------------------------------------------------------------
// About Functions
//
// Now that you've seen how to bind a name to a value with let,
// you'll learn to use the let keyword to create functions.
//---------------------------------------------------------------

// ---- creating functions with let -----------------------------

(* By default, F# is whitespace sensitive. For functions, this 
   means that the last line of a function is its return value,
   and the body of a function is denoted by indentation. *)

let add x y =
    x + y

let result1 = add 2 2
let result2 = add 5 2

AssertEquality result1 __
AssertEquality result2 __

//---------------------------------------------------------------

// ---- nesting functions ---------------------------------------

let quadruple x =    
    let double x =
        x * 2

    double(double(x))

let result = quadruple 4
AssertEquality result __

//---------------------------------------------------------------

// ---- adding type annotations ---------------------------------

(* Sometimes you need to help F#'s type inference system out with
   an explicit type annotation *)

let sayItLikeAnAuctioneer (text:string) =
    text.Replace(" ", "")

let auctioneered = sayItLikeAnAuctioneer "going once going twice sold to the lady in red"
AssertEquality auctioneered __

//TRY IT: What happens if you remove the type annotation on text?

//---------------------------------------------------------------

// ---- variables in the parent scope can be accessed -----------

let suffix = "!!!"

let caffinate (text:string) =
    let exclaimed = text + suffix
    let yelled = exclaimed.ToUpper()
    yelled.Trim()

let caffinatedReply = caffinate "hello there"

AssertEquality caffinatedReply __

(* NOTE: Accessing the suffix variable in the nested caffinate function 
         is known as a closure. 
         
         See http://en.wikipedia.org/wiki/Closure_(computer_science) 
         for more about about closure. *)

//---------------------------------------------------------------

//---------------------------------------------------------------
// About the Order of Evaluation
//
// Sometimes you'll need to be explicit about the order in which
// functions are evaluated. F# offers a couple mechanisms for
// doing this.
//---------------------------------------------------------------

// ---- using parenthesis to control the order of operation -----

let add x y =
    x + y

let result = add (add 5 8) (add 1 1)

AssertEquality result __

(* TRY IT: What happens if you remove the parensthesis?*)

//---------------------------------------------------------------

// ---- the backward pipe operator can also help with grouping --

let add x y =
    x + y

let double x =
    x * 2

let result = double <| add 5 8

AssertEquality result __

//---------------------------------------------------------------

//---------------------------------------------------------------
// About Unit
//
// The unit type is a special type that represents the lack of
// a value. It's similar to void in other languages, but unit
// is actually considered to be a type in F#.
//---------------------------------------------------------------

// ---- unit is used when there is no return value --------------
let sendData data =
    //...pretend we are sending the data to the server...
    ()

let x = sendData "data"
AssertEquality x __ //Don't overthink this

//---------------------------------------------------------------

// ---- parameterless fucntions take unit as their argument -----

let sayHello() =
    "hello"

let result = sayHello()
AssertEquality result __

//---------------------------------------------------------------

//---------------------------------------------------------------
// Tuples
//
// Tuples are used to easily group together values in F#. They're 
// another fundamental construct of the language.
//---------------------------------------------------------------

// ---- creating tuples -----

let items = ("apple", "dog")

AssertEquality items ("apple", __)

//---------------------------------------------------------------

// ---- accessing tuple elements --------------------------------

let items = ("apple", "dog")
 
let fruit = fst items
let animal = snd items
 
AssertEquality fruit __
AssertEquality animal __

//---------------------------------------------------------------
       
// ---- accessing tuple elements with pattern matching ----------

(* fst and snd are useful in some situations, but they only work with
   tuples containing two elements. It's usually better to use a 
   technique called pattern matching to access the values of a tuple. 
    
   Pattern matching works with tuples of any arity, and it allows you to 
   simultaneously break apart the tuple while assigning a name to each 
   value. Here's an example. *)

let items = ("apple", "dog", "Mustang")

let fruit, animal, car = items

AssertEquality fruit __
AssertEquality animal __
AssertEquality car __

//---------------------------------------------------------------
        
// ---- ignoring values when pattern matching -------------------
       
let items = ("apple", "dog", "Mustang")

let _, animal, _ = items

AssertEquality animal __
    
//---------------------------------------------------------------
        
// ---- using tuples to return multiple values from a function --

let squareAndCube x =
    (x ** 2.0, x ** 3.0)

let squared, cubed = squareAndCube 3.0


AssertEquality squared __
AssertEquality cubed __

(* THINK ABOUT IT: Is there really more than one return value?
                   What type does the squareAndCube function
                   return? *)

//---------------------------------------------------------------

// ---- the truth behind multiple return values ------------------

let squareAndCube x =
    (x ** 2.0, x ** 3.0)
            
let result = squareAndCube 3.0
       
AssertEquality result __
    
//---------------------------------------------------------------

//---------------------------------------------------------------
// Branching
//
// Branching is used to tell a program to conditionally perform
// an operation. It's another fundamental part of F#.
//---------------------------------------------------------------

// ---- basic if statements -------------------------------------

let isEven x =
    if x % 2 = 0 then
        "it's even!"
    else
        "it's odd!"
        
let result = isEven 2                
AssertEquality result __

//---------------------------------------------------------------

// ---- if statements return values -----------------------------
    
(* In languages like C++, Java, and C# if statements do not yield 
  results; they can only cause side effects. If statements in F# 
  return values due to F#'s functional programming roots. *)
   
let result = 
    if 2 = 3 then
        "something is REALLY wrong"
    else
        "math is workng!"

AssertEquality result __

//---------------------------------------------------------------

// ---- branching with pattern matching -------------------------
 
let isApple x =
    match x with
    | "apple" -> true
    | _ -> false

let result1 = isApple "apple"
let result2 = isApple ""

AssertEquality result1 __
AssertEquality result2 __

//---------------------------------------------------------------

// ---- using tuples with if statements quickly becomes clumsy --
        
let getDinner x = 
    let name, foodChoice = x
    
    if foodChoice = "veggies" || foodChoice ="fish" || 
       foodChoice = "chicken" then
        sprintf "%s doesn't want red meat" name
    else
        sprintf "%s wants 'em some %s" name foodChoice
 
let person1 = ("Chris", "steak")
let person2 = ("Dave", "veggies")

AssertEquality (getDinner person1) __
AssertEquality (getDinner person2) __

//---------------------------------------------------------------

// ---- pattern matching with tuples is much nicer --------------
    
let getDinner x =
    match x with
    | (name, "veggies")
    | (name, "fish")
    | (name, "chicken") -> sprintf "%s doesn't want red meat" name
    | (name, foodChoice) -> sprintf "%s wants 'em some %s" name foodChoice 
    
let person1 = ("Bob", "fish")
let person2 = ("Sally", "Burger")

AssertEquality (getDinner person1) __
AssertEquality (getDinner person2) __

//---------------------------------------------------------------

//---------------------------------------------------------------
// About Lists
//
// Lists are important building blocks that you'll use frequently
// in F# programming. They are used to group arbitrarily large 
// sequences of values. It's very common to store values in a 
// list and perform operations across each value in the 
// list.
//---------------------------------------------------------------

// ---- creating lists ------------------------------------------

let list = ["apple"; "pear"; "grape"; "peach"]

//Note: The list data type in F# is a singly linked list, 
//      so indexing elements is O(n). 
 
AssertEquality list.Head __
AssertEquality list.Tail __
AssertEquality list.Length __

       
(* .NET developers coming from other languages may be surprised
   that F#'s list type is not the same as the base class library's
   List<T>. In other words, the following assertion is true *)

let dotNetList = new List<string>()

//you don't need to modify the following line
AssertInequality (list.GetType()) (dotNetList.GetType())

//---------------------------------------------------------------

// ---- building new lists---------------------------------------

let first = ["grape"; "peach"]
let second = "pear" :: first
let third = "apple" :: second

//Note: "::" is known as "cons"

AssertEquality ["apple"; "pear"; "grape"; "peach"] third
AssertEquality second __
AssertEquality first __

//What happens if you uncomment the following?

//first.Head <- "apple"
//first.Tail <- ["peach"; "pear"]

//THINK ABOUT IT: Can you change the contents of a list once it 
//                has been created?

//---------------------------------------------------------------

// ---- concatenating lists -------------------------------------

let first = ["apple"; "pear"; "grape"]
let second = first @ ["peach"]

AssertEquality first __
AssertEquality second __

(* THINK ABOUT IT: In general, what performs better for building lists, 
   :: or @? Why?
   
   Hint: There is no way to modify "first" in the above example. It's
   immutable. With that in mind, what does the @ function have to do in
   order to append ["peach"] to "first" to create "second"? *)

//---------------------------------------------------------------

// ---- creating lists with a range------------------------------

let list = [0..4]

AssertEquality list.Head __
AssertEquality list.Tail __

//---------------------------------------------------------------

// ---- creating lists with comprehensions-----------------------

let list = [for i in 0..4 do yield i ]
                            
AssertEquality list __

//---------------------------------------------------------------
    
// ---- comprehensions with conditions --------------------------

let list = [for i in 0..10 do 
                if i % 2 = 0 then yield i ]
                    
AssertEquality list __

//---------------------------------------------------------------

// ---- transforming lists with map -----------------------------

let square x =
    x * x

let original = [0..5]
let result = List.map square original

AssertEquality original __
AssertEquality result __

//---------------------------------------------------------------

// ---- filtering lists with where ------------------------------

let isEven x =
    x % 2 = 0

let original = [0..5]
let result = List.filter isEven original

AssertEquality original __
AssertEquality result __

//---------------------------------------------------------------

// ---- dividing lists with partition ---------------------------

let isOdd x =
    not(x % 2 = 0)

let original = [0..5]
let result1, result2 = List.partition isOdd original

AssertEquality result1 __
AssertEquality result2 __

//---------------------------------------------------------------

(* Note: There are many other useful methods in the List module. Check them
   via intellisense in Visual Studio by typing '.' after List, or online at
   http://msdn.microsoft.com/en-us/library/ee353738.aspx *)

//---------------------------------------------------------------
// Pipelining
//
// The forward pipe operator is one of the most commonly used
// symbols in F# programming. You can use it combine operations
// on lists and other data structures in a readable way.
//---------------------------------------------------------------


// ---- square even numbers with separate statementes -----------

let square x =
    x * x

let isEven x =
    x % 2 = 0

(* One way to combine operations is by using separate statements.
   However, this is can be clumsy since you have to name each result. *)

let numbers = [0..5]

let evens = List.filter isEven numbers
let result = List.map square evens

AssertEquality result __

//---------------------------------------------------------------

// ---- square even numbers with parens -------------------------

(* You can avoid this problem by using parens to pass the result of one
   funciton to another. This can be difficult to read since you have to 
   start from the innermost function and work your way out. *)

let numbers = [0..5]

let result = List.map square (List.filter isEven numbers)

AssertEquality result __

//---------------------------------------------------------------

// ---- square even numbers with  the pipeline operator ---------

(* In F#, you can use the pipeline operator to get the benefit of the 
   parens style with the readablity of the statement style. *)

let result =
    [0..5]
    |> List.filter isEven
    |> List.map square

AssertEquality result __

//---------------------------------------------------------------

// ---- how the pipe operator is defined ------------------------

let (|>) x y =
    y x

let result =
    [0..5]
    |> List.filter isEven
    |> List.map square

AssertEquality result __

//---------------------------------------------------------------

//---------------------------------------------------------------
// Arrays
//
// Like lists, arrays are another basic container type in F#.
//---------------------------------------------------------------

// ---- creating arrays -----------------------------------------

let fruits = [| "apple"; "pear"; "peach"|]

AssertEquality fruits.[0] __
AssertEquality fruits.[1] __
AssertEquality fruits.[2] __

//---------------------------------------------------------------

// ---- arrays are mutable --------------------------------------

let fruits = [| "apple"; "pear" |]
fruits.[1] <- "peach"

AssertEquality fruits __

//---------------------------------------------------------------

// ---- you can create arrays with comprehensions ---------------

let numbers = 
    [| for i in 0..10 do 
           if i % 2 = 0 then yield i |]

AssertEquality numbers __

//---------------------------------------------------------------

// ---- you can also perform operations on arrays ---------------

let cube x =
    x * x * x

let original = [| 0..5 |]
let result = Array.map cube original

AssertEquality original __
AssertEquality result __

(* See more Array methods at
   http://msdn.microsoft.com/en-us/library/ee370273.aspx *)

//---------------------------------------------------------------

//---------------------------------------------------------------
// .NET Collections
//
// Since F# is bulit for seamless interop with other CLR 
// languages, you can use all of the basic .NET collections types
// you're already familiar with if you're a C# or VB programmer.
//---------------------------------------------------------------

// ---- creating .NET lists -------------------------------------

let fruits = new List<string>()

fruits.Add("apple")
fruits.Add("pear")

AssertEquality fruits.[0] __
AssertEquality fruits.[1] __

//---------------------------------------------------------------

// ---- creating .NET dictionaries ------------------------------

let addressBook = new Dictionary<string, string>()

addressBook.["Chris"] <- "Ann Arbor"
addressBook.["SkillsMatter"] <- "London"

AssertEquality addressBook.["Chris"] __
AssertEquality addressBook.["SkillsMatter"] __

//---------------------------------------------------------------

// ---- you can use combinators with .NET types  ----------------

let addressBook = new Dictionary<string, string>()

addressBook.["Chris"] <- "Ann Arbor"
addressBook.["SkillsMatter"] <- "London"

let verboseBook = 
    addressBook
    |> Seq.map (fun kvp -> sprintf "Name: %s - City: %s" kvp.Key kvp.Value)
    |> Seq.toArray

//NOTE: The seq type in F# is an alias for .NET's IEnumerable interface
//      Like the List and Array module, the Seq module contains functions 
//      that you can combine to perform operations on types implementing 
//      seq/IEnumerable. The methods found in these modules are known as
//      combinators

AssertEquality verboseBook.[0] __
AssertEquality verboseBook.[1] __

//---------------------------------------------------------------

// ---- skipping elements ---------------------------------------

let original = [0..5]
let result = Seq.skip 2 original

AssertEquality result __

//---------------------------------------------------------------

// ---- finding the max -----------------------------------------

let values = new List<int>()

values.Add(11)
values.Add(20)
values.Add(4)
values.Add(2)
values.Add(3)

let result = Seq.max values

AssertEquality result __
    
//---------------------------------------------------------------

// ---- finding the max using a condition -----------------------

let getNameLength (name:string) =
    name.Length

let names = [| "Harry"; "Lloyd"; "Nicholas"; "Mary"; "Joe"; |]
let result = Seq.maxBy getNameLength names 

AssertEquality result __

//---------------------------------------------------------------

//---------------------------------------------------------------
// Looping
//
// While it's more common in F# to use the Seq, List, or Array
// modules to perform looping operations, you can still fall 
// back on traditional imperative looping techniques that you may 
// be more familiar with.
//---------------------------------------------------------------

// ---- looping over a list -------------------------------------

let values = [0..10]

let mutable sum = 0
for value in values do
    sum <- sum + value

AssertEquality sum __
       
//---------------------------------------------------------------

// ---- looping with expressions --------------------------------

let mutable sum = 0

for i = 1 to 5 do
    sum <- sum + i

AssertEquality sum __

//---------------------------------------------------------------

// ---- looping with while --------------------------------------

let mutable sum = 1

while sum < 10 do
    sum <- sum + sum

AssertEquality sum __

(* NOTE: While these looping constructs can come in handy from time to time,
         it's often better to use a more functional approach for looping
         such as the functions you learned about in the List module. *)

//---------------------------------------------------------------

//---------------------------------------------------------------
// More About Funtions
//
// You've already learned a little about funcitons in F#, but
// since F# is a functional language, there are more tricks
// to learn!
//---------------------------------------------------------------

// ---- defining lambdas ----------------------------------------

let colors = ["maize"; "blue"]

let echo = 
    colors
    |> List.map (fun x -> x + " " + x)

AssertEquality echo __

(* The fun keyword allows you to create a function inline without giving
   it a name. These functions are known as anonymous functions, lambdas,
   or lambda functions. *)

//---------------------------------------------------------------

// ---- functions that return functions  ------------------------

(* A neat functional programming trick is to create functions that 
   return other functions. This leads to some interesting behaviors. *)
let add x =
    (fun y -> x + y)

(* F#'s lightweight syntax allows you to call both functions as if there
   was only one *)
let simpleResult = add 2 4
AssertEquality simpleResult __

(* ...but you can also pass only one argument at a time to create
   residual functions. This technique is known as partial appliction. *)
let addTen = add 10
let fancyResult = addTen 14

AssertEquality fancyResult __

//NOTE: Functions written in this style are said to be curried.

//---------------------------------------------------------------

// ---- automatic currying --------------------------------------

(* The above technique is common enough that F# actually supports this
   by default. In other words, functions are automatically curried. *)
let add x y = 
    x + y

let addSeven = add 7
let unluckyNumber = addSeven 6
let luckyNumber = addSeven 0

AssertEquality unluckyNumber __
AssertEquality luckyNumber __

//---------------------------------------------------------------

// ---- non curried functions -----------------------------------

(* You should stick to the auto-curried function syntax most of the 
   time. However, you can also write functions in an uncurried form to
   make them easier to use from languages like C# where currying is not 
   as commonly used. *)

let add(x, y) =
    x + y

(* NOTE: "add 5" will not compile now. You have to pass both arguments 
         at once *)

let result = add(5, 40)

AssertEquality result __

(* THINK ABOUT IT: You learned earlier that functions with multiple 
                   return values are really just functions that return
                   tuples. Do functions defined in the uncurried form
                   really accept more than one argument at a time? *)

//---------------------------------------------------------------

//---------------------------------------------------------------
// Apply Your Knowledge!
//
// Below is a list containing comma separated data about 
// Microsoft's stock prices during March of 2012. Without
// modifying the list, programatically find the day with the
// greatest variance between the opening and closing price.
//
// The following functions may be of use:
// 
// abs - takes the absolute value of an arguement
// 
// System.Double.Parse - converts a string argument into a 
//                       numerical value.
//
// The following function will convert a comma separated string
// into an array of the column values.
//                       
// let splitCommas (x:string) =
//     x.Split([|','|])
//---------------------------------------------------------------
    
let stockData =
    [ "Date,Open,High,Low,Close,Volume,Adj Close";
      "2012-03-30,32.40,32.41,32.04,32.26,31749400,32.26";
      "2012-03-29,32.06,32.19,31.81,32.12,37038500,32.12";
      "2012-03-28,32.52,32.70,32.04,32.19,41344800,32.19";
      "2012-03-27,32.65,32.70,32.40,32.52,36274900,32.52";
      "2012-03-26,32.19,32.61,32.15,32.59,36758300,32.59";
      "2012-03-23,32.10,32.11,31.72,32.01,35912200,32.01";
      "2012-03-22,31.81,32.09,31.79,32.00,31749500,32.00";
      "2012-03-21,31.96,32.15,31.82,31.91,37928600,31.91";
      "2012-03-20,32.10,32.15,31.74,31.99,41566800,31.99";
      "2012-03-19,32.54,32.61,32.15,32.20,44789200,32.20";
      "2012-03-16,32.91,32.95,32.50,32.60,65626400,32.60";
      "2012-03-15,32.79,32.94,32.58,32.85,49068300,32.85";
      "2012-03-14,32.53,32.88,32.49,32.77,41986900,32.77";
      "2012-03-13,32.24,32.69,32.15,32.67,48951700,32.67";
      "2012-03-12,31.97,32.20,31.82,32.04,34073600,32.04";
      "2012-03-09,32.10,32.16,31.92,31.99,34628400,31.99";
      "2012-03-08,32.04,32.21,31.90,32.01,36747400,32.01";
      "2012-03-07,31.67,31.92,31.53,31.84,34340400,31.84";
      "2012-03-06,31.54,31.98,31.49,31.56,51932900,31.56";
      "2012-03-05,32.01,32.05,31.62,31.80,45240000,31.80";
      "2012-03-02,32.31,32.44,32.00,32.08,47314200,32.08";
      "2012-03-01,31.93,32.39,31.85,32.29,77344100,32.29";
      "2012-02-29,31.89,32.00,31.61,31.74,59323600,31.74"; ]

//start your program here

let result =  __ //and put your result here to check your work

AssertEquality "2012-3-13" result


// ---------------------------------------------------------------
// Record Types
// 
// In F#, Record Types are lightweight objects that are used to
// bundle bits of data together as properties on an object and 
// give those properties meaningful names.
// ---------------------------------------------------------------

// ---- records have properties ----------------------------------

type Character = {
    Name: string
    Occupation: string
}

let mario = { Name = "Mario"; Occupation = "Plumber"; }

AssertEquality mario.Name __
AssertEquality mario.Occupation __

// ---------------------------------------------------------------

// ---- creating from an existing record -------------------------

let mario = { Name = "Mario"; Occupation = "Plumber"; }
let luigi = { mario with Name = "Luigi"; }

AssertEquality mario.Name __
AssertEquality mario.Occupation __

AssertEquality luigi.Name __
AssertEquality luigi.Occupation __

// ---------------------------------------------------------------

// ---- comparing records ----------------------------------------

let greenKoopa = { Name = "Koopa"; Occupation = "Soldier"; }
let bowser = { Name = "Bowser"; Occupation = "Kidnapper"; }
let redKoopa = { Name = "Koopa"; Occupation = "Soldier"; }

let koopaComparison =
     if greenKoopa = redKoopa then
         "all the koopas are pretty much the same"
     else
         "maybe one can fly"

let bowserComparison = 
    if bowser = greenKoopa then
        "the king is a pawn"
    else
        "he is still kind of a koopa"

AssertEquality koopaComparison __
AssertEquality bowserComparison __

// ---------------------------------------------------------------

// ---- you can pattern match against records --------------------

let mario = { Name = "Mario"; Occupation = "Plumber"; }
let luigi = { Name = "Luigi"; Occupation = "Plumber"; }
let bowser = { Name = "Bowser"; Occupation = "Kidnapper"; }

let determineSide character =
    match character with
    | { Occupation = "Plumber" } -> "good guy"
    | _ -> "bad guy"

AssertEquality (determineSide mario) __
AssertEquality (determineSide luigi) __
AssertEquality (determineSide bowser) __

// ---------------------------------------------------------------

// ---------------------------------------------------------------
// Option Types
//
// Option Types are used to represent calculations that may or
// may not return a value. You may be used to using null for this
// in other languages. However, using option types instead of nulls
// has subtle but far reaching benefits.
// ---------------------------------------------------------------

// ---- option types might contain a value... --------------------

let someValue = Some 10

AssertEquality someValue.IsSome __
AssertEquality someValue.IsNone __
AssertEquality someValue.Value __

// ---------------------------------------------------------------

// ---- ...but they might not ------------------------------------
let noValue = None

AssertEquality noValue.IsSome __
AssertEquality noValue.IsNone __
AssertThrows<FILL_IN_THE_EXCEPTION> (fun () -> noValue.Value)

// ---------------------------------------------------------------

// ---- using option types with pattern matching -----------------

type Game = {
    Name: string
    Platform: string
    Score: int option
}

let chronoTrigger = { Name = "Chrono Trigger"; Platform = "SNES"; Score = Some 5 }
let halo = { Name = "Halo"; Platform = "Xbox"; Score = None }

let translate score =
    match score with
    | 5 -> "Great"
    | 4 -> "Good"
    | 3 -> "Decent"
    | 2 -> "Bad"
    | 1 -> "Awful"
    | _ -> "Unknown"

let getScore game =
    match game.Score with
    | Some score -> translate score
    | None -> "Unknown"

AssertEquality (getScore chronoTrigger) __
AssertEquality (getScore halo) __

// ---------------------------------------------------------------

// ---- projecting values from option types ----------------------

let chronoTrigger = { Name = "Chrono Trigger"; Platform = "SNES"; Score = Some 5 }
let gta = { Name = "Halo"; Platform = "Xbox"; Score = None }

let decideOn game =
    game.Score
    |> Option.map (fun score -> if score > 3 then "play it" else "don't play")

//HINT: look at the return type of the decide on function
AssertEquality (decideOn chronoTrigger) __
AssertEquality (decideOn gta) __

// ---------------------------------------------------------------

// ---------------------------------------------------------------
// Discriminated Unions
//
// Discriminated Unions are used to represent data types that have
// a discrete set of possible states.
// ---------------------------------------------------------------

// ---- descriminated unions capture a set of options ------------

type Condiment =
    | Mustard
    | Ketchup
    | Relish
    | Vinegar

let toColor condiment = 
    match condiment with
    | Mustard -> "yellow"
    | Ketchup -> "red"
    | Relish -> "green"
    | Vinegar -> "brownish?"

let choice = Mustard

AssertEquality (toColor choice) __

(* TRY IT: What happens if you remove a case from the above pattern 
           match? *)

// ---------------------------------------------------------------

// ---- descriminated union cases can have types -----------------

type Favorite =
    | Bourbon of string
    | Number of int

let saySomethingAboutYourFavorite favorite =
    match favorite with
    | Number 7 -> "me too!"
    | Bourbon "Bookers" -> "me too!"
    | Bourbon b -> "I prefer Bookers to " + b
    | Number _ -> "I'm partial to 7"

let bourbonResult = saySomethingAboutYourFavorite <| Bourbon "Maker's Mark"
let numberResult = saySomethingAboutYourFavorite <| Number 7

AssertEquality bourbonResult __
AssertEquality numberResult __

// ---------------------------------------------------------------


//---------------------------------------------------------------
// Modules
//
// Modules are used to group funcitons, values, and types. 
// They're similar to .NET namespaces, but they have slightly 
// different semantics as you'll see below.
//---------------------------------------------------------------

// ---- modules can contain values and types --------------------

module MushroomKingdom =
    type Power =
        | Mushroom
        | Star
        | FireFlower
        
    type Character = {
        Name: string
        Occupation: string
        Power: Power option
    }

    let Mario = { Name = "Mario"; Occupation = "Plumber"; Power = None}

    let powerUp character =
        { character with Power = Some Mushroom }


AssertEquality MushroomKingdom.Mario.Name __
AssertEquality MushroomKingdom.Mario.Occupation __

let moduleType = MushroomKingdom.Mario.GetType()
AssertEquality moduleType typeof<FILL_ME_IN>

//---------------------------------------------------------------

// ---- modules can contain functions ---------------------------

let superMario = MushroomKingdom.powerUp MushroomKingdom.Mario

AssertEquality superMario.Power __

(* NOTE: In previous sections, you've seen modules like List and Option that 
         contain useful functions for dealing with List types and Option types
         respectively. *)

//---------------------------------------------------------------

// ---- opened modules ------------------------------------------
open MushroomKingdom

let OpenedModulesBringTheirContentsInScope() = 
    AssertEquality Mario.Name __
    AssertEquality Mario.Occupation __

//---------------------------------------------------------------

//---------------------------------------------------------------
// Classes
//
// As a full fledged Object Oriented language, F# allows you to
// create traditional classes to contain data and methods.
//---------------------------------------------------------------

// ---- classes can have properties -----------------------------

type Zombie() =
    member this.FavoriteFood = "brains"

    member this.Eat food =
        match food with
        | "brains" -> "mmmmmmmmmmmmmmm"
        | _ -> "grrrrrrrr"

let zombie = new Zombie()

AssertEquality zombie.FavoriteFood __

//---------------------------------------------------------------

// ---- classes can have methods --------------------------------

let zombie = new Zombie()

let result = zombie.Eat "brains"
AssertEquality result __

//---------------------------------------------------------------
 
// ---- classes can have constructors ---------------------------

type Person(name:string) =
    member this.Speak() =
        "Hi my name is " + name

    
let person = new Person("Shaun")

let result = person.Speak()
AssertEquality result __

//---------------------------------------------------------------

// ---- classes can have let bindings in them -------------------

type Zombie2() =
    let favoriteFood = "brains"

    member this.Eat food =
        if food = favoriteFood then "mmmmmmmmmmmmmmm" else "grrrrrrrr"

let zombie = new Zombie2()

let result = zombie.Eat "chicken"
AssertEquality result __

(* TRY IT: Can you access the let bound value Zombie2.favoriteFood
           outside of the class definition? *)

//---------------------------------------------------------------

// ---- classes can have read write properties ------------------

type Person2(name:string) =
    let mutable internalName = name

    member this.Name
        with get() = internalName
        and set(value) = internalName <- value

    member this.Speak() =
        "Hi my name is " + this.Name

let person = new Person2("Shaun")

let firstPhrase = person.Speak()
AssertEquality firstPhrase __

person.Name <- "Shaun of the Dead"
let secondPhrase = person.Speak()
AssertEquality secondPhrase __

//---------------------------------------------------------------
val expected_value : int

Full name: Script.expected_value
val actual_value : obj

Full name: Script.actual_value
val x : int

Full name: Script.x
val typeOfX : System.Type

Full name: Script.typeOfX
System.Object.GetType() : System.Type
val typeof<'T> : System.Type

Full name: Microsoft.FSharp.Core.Operators.typeof
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val y : string

Full name: Script.y
val expectedType : System.Type

Full name: Script.expectedType
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
val typeOfY : System.Type

Full name: Script.typeOfY
val y : float

Full name: Script.y
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val mutable x : int

Full name: Script.x
val add : x:int -> y:int -> int

Full name: Script.add
val x : int
val y : int
val result1 : int

Full name: Script.result1
val result2 : int

Full name: Script.result2
val quadruple : x:int -> int

Full name: Script.quadruple
Multiple items
val double : (int -> int)

--------------------
type double = System.Double

Full name: Microsoft.FSharp.Core.double
val result : int

Full name: Script.result
val sayItLikeAnAuctioneer : text:string -> string

Full name: Script.sayItLikeAnAuctioneer
val text : string
System.String.Replace(oldValue: string, newValue: string) : string
System.String.Replace(oldChar: char, newChar: char) : string
val auctioneered : string

Full name: Script.auctioneered
val suffix : string

Full name: Script.suffix
val caffinate : text:string -> string

Full name: Script.caffinate
val exclaimed : string
val yelled : string
System.String.ToUpper() : string
System.String.ToUpper(culture: System.Globalization.CultureInfo) : string
System.String.Trim() : string
System.String.Trim([<System.ParamArray>] trimChars: char []) : string
val caffinatedReply : string

Full name: Script.caffinatedReply
Multiple items
val double : x:int -> int

Full name: Script.double

--------------------
type double = System.Double

Full name: Microsoft.FSharp.Core.double
val sendData : data:'a -> unit

Full name: Script.sendData
val data : 'a
val x : unit

Full name: Script.x
val sayHello : unit -> string

Full name: Script.sayHello
val result : string

Full name: Script.result
val items : string * string

Full name: Script.items
val fruit : string

Full name: Script.fruit
val fst : tuple:('T1 * 'T2) -> 'T1

Full name: Microsoft.FSharp.Core.Operators.fst
val animal : string

Full name: Script.animal
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
val items : string * string * string

Full name: Script.items
val car : string

Full name: Script.car
val squareAndCube : x:float -> float * float

Full name: Script.squareAndCube
val x : float
val squared : float

Full name: Script.squared
val cubed : float

Full name: Script.cubed
val result : float * float

Full name: Script.result
val isEven : x:int -> string

Full name: Script.isEven
val isApple : x:string -> bool

Full name: Script.isApple
val x : string
val result1 : bool

Full name: Script.result1
val result2 : bool

Full name: Script.result2
val getDinner : string * string -> string

Full name: Script.getDinner
val x : string * string
val name : string
val foodChoice : string
val sprintf : format:Printf.StringFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val person1 : string * string

Full name: Script.person1
val person2 : string * string

Full name: Script.person2
Multiple items
val list : string list

Full name: Script.list

--------------------
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
property List.Head: string
property List.Tail: string list
property List.Length: int
val dotNetList : List<string>

Full name: Script.dotNetList
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val first : string list

Full name: Script.first
val second : string list

Full name: Script.second
val third : string list

Full name: Script.third
Multiple items
val list : int list

Full name: Script.list

--------------------
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
property List.Head: int
property List.Tail: int list
val i : int
val square : x:int -> int

Full name: Script.square
val original : int list

Full name: Script.original
val result : int list

Full name: Script.result
val map : mapping:('T -> 'U) -> list:'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
val isEven : x:int -> bool

Full name: Script.isEven
val filter : predicate:('T -> bool) -> list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.filter
val isOdd : x:int -> bool

Full name: Script.isOdd
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
val result1 : int list

Full name: Script.result1
val result2 : int list

Full name: Script.result2
val partition : predicate:('T -> bool) -> list:'T list -> 'T list * 'T list

Full name: Microsoft.FSharp.Collections.List.partition
val numbers : int list

Full name: Script.numbers
val evens : int list

Full name: Script.evens
val x : 'a
val y : ('a -> 'b)
val fruits : string []

Full name: Script.fruits
val numbers : int []

Full name: Script.numbers
val cube : x:int -> int

Full name: Script.cube
val original : int []

Full name: Script.original
val result : int []

Full name: Script.result
module Array

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []

Full name: Microsoft.FSharp.Collections.Array.map
val fruits : List<string>

Full name: Script.fruits
val addressBook : obj

Full name: Script.addressBook
val addressBook : seq<obj>

Full name: Script.addressBook
val verboseBook : string []

Full name: Script.verboseBook
module Seq

from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val kvp : obj
val toArray : source:seq<'T> -> 'T []

Full name: Microsoft.FSharp.Collections.Seq.toArray
val result : seq<int>

Full name: Script.result
val skip : count:int -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.skip
val values : List<int>

Full name: Script.values
val max : source:seq<'T> -> 'T (requires comparison)

Full name: Microsoft.FSharp.Collections.Seq.max
val getNameLength : name:string -> int

Full name: Script.getNameLength
property System.String.Length: int
val names : string []

Full name: Script.names
val maxBy : projection:('T -> 'U) -> source:seq<'T> -> 'T (requires comparison)

Full name: Microsoft.FSharp.Collections.Seq.maxBy
val values : int list

Full name: Script.values
val mutable sum : int

Full name: Script.sum
val value : int
val colors : string list

Full name: Script.colors
val echo : string list

Full name: Script.echo
val simpleResult : int

Full name: Script.simpleResult
val addTen : (int -> int)

Full name: Script.addTen
val fancyResult : int

Full name: Script.fancyResult
val addSeven : (int -> int)

Full name: Script.addSeven
val unluckyNumber : int

Full name: Script.unluckyNumber
val luckyNumber : int

Full name: Script.luckyNumber
val add : x:int * y:int -> int

Full name: Script.add
val stockData : string list

Full name: Script.stockData
val result : obj

Full name: Script.result
type Character =
  {Name: string;
   Occupation: string;}

Full name: Script.Character
Character.Name: string
Character.Occupation: string
val mario : Character

Full name: Script.mario
val luigi : Character

Full name: Script.luigi
val greenKoopa : Character

Full name: Script.greenKoopa
val bowser : Character

Full name: Script.bowser
val redKoopa : Character

Full name: Script.redKoopa
val koopaComparison : string

Full name: Script.koopaComparison
val bowserComparison : string

Full name: Script.bowserComparison
val determineSide : character:Character -> string

Full name: Script.determineSide
val character : Character
val someValue : int option

Full name: Script.someValue
union case Option.Some: Value: 'T -> Option<'T>
property Option.IsSome: bool
property Option.IsNone: bool
property Option.Value: int
val noValue : 'a option

Full name: Script.noValue
union case Option.None: Option<'T>
type Game =
  {Name: string;
   Platform: string;
   Score: int option;}

Full name: Script.Game
Game.Name: string
Game.Platform: string
Game.Score: int option
type 'T option = Option<'T>

Full name: Microsoft.FSharp.Core.option<_>
val chronoTrigger : Game

Full name: Script.chronoTrigger
val halo : Game

Full name: Script.halo
val translate : score:int -> string

Full name: Script.translate
val score : int
val getScore : game:Game -> string

Full name: Script.getScore
val game : Game
val gta : Game

Full name: Script.gta
val decideOn : game:Game -> string option

Full name: Script.decideOn
module Option

from Microsoft.FSharp.Core
val map : mapping:('T -> 'U) -> option:'T option -> 'U option

Full name: Microsoft.FSharp.Core.Option.map
type Condiment =
  | Mustard
  | Ketchup
  | Relish
  | Vinegar

Full name: Script.Condiment
union case Condiment.Mustard: Condiment
union case Condiment.Ketchup: Condiment
union case Condiment.Relish: Condiment
union case Condiment.Vinegar: Condiment
val toColor : condiment:Condiment -> string

Full name: Script.toColor
val condiment : Condiment
val choice : Condiment

Full name: Script.choice
type Favorite =
  | Bourbon of string
  | Number of int

Full name: Script.Favorite
union case Favorite.Bourbon: string -> Favorite
union case Favorite.Number: int -> Favorite
val saySomethingAboutYourFavorite : favorite:Favorite -> string

Full name: Script.saySomethingAboutYourFavorite
val favorite : Favorite
val b : string
val bourbonResult : string

Full name: Script.bourbonResult
val numberResult : string

Full name: Script.numberResult
type Power =
  | Mushroom
  | Star
  | FireFlower

Full name: Script.MushroomKingdom.Power
union case Power.Mushroom: Power
union case Power.Star: Power
union case Power.FireFlower: Power
type Character =
  {Name: string;
   Occupation: string;
   Power: Power option;}

Full name: Script.MushroomKingdom.Character
Multiple items
Character.Power: Power option

--------------------
type Power =
  | Mushroom
  | Star
  | FireFlower

Full name: Script.MushroomKingdom.Power
val Mario : Character

Full name: Script.MushroomKingdom.Mario
val powerUp : character:Character -> Character

Full name: Script.MushroomKingdom.powerUp
module MushroomKingdom

from Script
val Mario : MushroomKingdom.Character

Full name: Script.MushroomKingdom.Mario
val moduleType : System.Type

Full name: Script.moduleType
val superMario : MushroomKingdom.Character

Full name: Script.superMario
val powerUp : character:MushroomKingdom.Character -> MushroomKingdom.Character

Full name: Script.MushroomKingdom.powerUp
MushroomKingdom.Character.Power: MushroomKingdom.Power option
val OpenedModulesBringTheirContentsInScope : unit -> 'a

Full name: Script.OpenedModulesBringTheirContentsInScope
Multiple items
type Zombie =
  new : unit -> Zombie
  member Eat : food:string -> string
  member FavoriteFood : string

Full name: Script.Zombie

--------------------
new : unit -> Zombie
val this : Zombie
member Zombie.FavoriteFood : string

Full name: Script.Zombie.FavoriteFood
member Zombie.Eat : food:string -> string

Full name: Script.Zombie.Eat
val food : string
val zombie : Zombie

Full name: Script.zombie
property Zombie.FavoriteFood: string
member Zombie.Eat : food:string -> string
Multiple items
type Person =
  new : name:string -> Person
  member Speak : unit -> string

Full name: Script.Person

--------------------
new : name:string -> Person
val this : Person
member Person.Speak : unit -> string

Full name: Script.Person.Speak
val person : Person

Full name: Script.person
member Person.Speak : unit -> string
Multiple items
type Zombie2 =
  new : unit -> Zombie2
  member Eat : food:string -> string

Full name: Script.Zombie2

--------------------
new : unit -> Zombie2
val favoriteFood : string
val this : Zombie2
member Zombie2.Eat : food:string -> string

Full name: Script.Zombie2.Eat
val zombie : Zombie2

Full name: Script.zombie
member Zombie2.Eat : food:string -> string
Multiple items
type Person2 =
  new : name:string -> Person2
  member Speak : unit -> string
  member Name : string
  member Name : string with set

Full name: Script.Person2

--------------------
new : name:string -> Person2
val mutable internalName : string
val this : Person2
member Person2.Name : string with set

Full name: Script.Person2.Name
val set : elements:seq<'T> -> Set<'T> (requires comparison)

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set
val value : string
member Person2.Speak : unit -> string

Full name: Script.Person2.Speak
property Person2.Name: string
val person : Person2

Full name: Script.person
val firstPhrase : string

Full name: Script.firstPhrase
member Person2.Speak : unit -> string
val secondPhrase : string

Full name: Script.secondPhrase

More information

Link:http://fssnip.net/bG
Posted:5 years ago
Author:Chris Marinos
Tags: f# koans