PureScript无法匹配类型Int Int和Int类型

时间:2018-02-14 04:35:45

标签: purescript

我正在“PureScript by example”一书中进行分配,使用递归来计算数组中偶数项的数量。

这是我写的代码

isEven :: Int -> Boolean
isEven 0 = true
isEven 1 = false
isEven n = isEven(n - 2) 

countEven :: List Int -> Int
countEven list = 
   if null list 
   then 0
   else 
      if isEven(unsafePartial (head list)) 
      then 1 
      else 0 + countEven(unsafePartial (tail list))

我收到一条错误消息

Error found:
in module Main
at src/Main.purs line 74, column 17 - line 74, column 42

  Could not match type

    Maybe Int

  with type

    Int


while checking that type t0
  is at least as general as type Int
while checking that expression unsafePartial (head list)
  has type Int
in binding group countEven

我对此感到有些惊讶,因为unsafePartial head list的数据类型是Int,而unsafePartial tail list是List Int

那为什么感觉到某个地方有一个可能?

2 个答案:

答案 0 :(得分:7)

您收到此错误的事实意味着您正在使用Data.List中的headtail,这些Maybe实际上并不是部分错误,而是返回{ {1}}。

要使用部分对应部分,请从Data.List.Partial导入。

答案 1 :(得分:1)

你应该使用uncons代替使用unsafePartial这样的重锤,因为它很容易从你的手中溜走......

如果你真的想亲自编写这个递归(我认为是反模式)你可以写如下:

module Main where

import Data.Array (uncons)
import Data.Maybe (Maybe(..))

isEven :: Int -> Boolean
isEven n = n `mod` 2 == 0

countEven l =
  case uncons l of
    Just { head, tail } ->
      let
        s =
         if isEven head
         then 1
         else 0
      in
        s + countEven tail
    Nothing -> 0

以下是try.purescript.org上此代码段的互动版本。

正如我上面所说,你应该避免使用unsafePartialPartial,因为它们会破坏你对程序整体的信心。 Totality是任何程序的非常有价值的功能。 总的来说,我认为使用更高级别的工具(例如foldfoldMap + ala比“原始递归程序集”更好。