ฉันกำลังเรียนรู้ Haskell และกำลังทำโปรแกรมฐานข้อมูลอย่างง่ายสำหรับ Yesod เมื่อฉันสะดุดกับพฤติกรรมนี้ซึ่งฉันเข้าใจยาก
testFn :: Int -> Bool -> [Int]
testFn a b = if b then replicate 10 a else []
Yesod GHCI เซสชั่น:
$ :t concatMap testFn [3]
concatMap testFn [3] :: Bool -> [Int]
$ (concatMap testFn [1,2,3]) True
[1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3]
อย่างใดก็สามารถ "ดึง" ออก "Bool" ที่สองจากการแมปแต่ละครั้งเป็นอาร์กิวเมนต์ curated เดียว
โหมโรง GHCI พื้นฐานแบบมาตรฐานปฏิเสธที่จะคอมไพล์นิพจน์นี้:
$ :t concatMap testFn [3]
error:
• Couldn't match type 'Bool -> [Int]' with '[b]'
Expected type: Int -> [b]
Actual type: Int -> Bool -> [Int]
• Probable cause: 'testFn' is applied to too few arguments
In the first argument of 'concatMap', namely 'testFn'
In the expression: concatMap testFn [3]
ปรากฎว่า Yesod ใช้ไลบรารีแบบ mono-traversableซึ่งมีconcatMap
:
$ :t concatMap
concatMap
:: (MonoFoldable mono, Monoid m) =>
(Element mono -> m) -> mono -> m
ที่ระดับปัจจุบันของฉันในการทำความเข้าใจแฮสเค็ลล์ฉันไม่สามารถทราบได้ว่าจะกระจายประเภทอย่างไรที่นี่ ใครสามารถอธิบายให้ฉัน (เริ่มต้นที่มุ่งเน้นมากที่สุดเท่าที่เป็นไปได้) วิธีการทำเคล็ดลับนี้? ส่วนใดของtestFn
ข้างต้นที่สอดคล้องกับElement mono
ประเภท