产生不同解释结果的等效函数

The*_*kle 6 lambda haskell map ghc ghci

背景:我正在调查匿名递归,我正在接受实现前奏的挑战而不使用任何命名的递归只是为了帮助它在我的脑海中完美地存在.我还没到那里,一路上我遇到了一些无关但仍然有趣的东西.

map1     = \f -> \x -> if (tail x) == [] 
                       then [f (head x)] 
                       else f (head x) : (map1 f (tail x))

map2 f x =             if (tail x) == [] 
                       then [f (head x)] 
                       else f (head x) : (map2 f (tail x))

map3 f (x:xs) = if xs == [] then [f x] else f x : (map3 f xs)

map4 f (x:[]) = [f x]
map4 f (x:xs) =  f x : map4 f xs
Run Code Online (Sandbox Code Playgroud)

GHC抱怨第一个,第二个是好的,第三个和第四个只是为了展示如何以不同的方式实现它们.

*Main> map1 (*2) [1..10]

<interactive>:1:15:
    No instance for (Num ())
      arising from the literal `10'
    Possible fix: add an instance declaration for (Num ())
    In the expression: 10
    In the second argument of `map1', namely `[1 .. 10]'
    In the expression: map1 (* 2) [1 .. 10]
*Main> map2 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
*Main> map3 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
*Main> map4 (*2) [1..10]
[2,4,6,8,10,12,14,16,18,20]
Run Code Online (Sandbox Code Playgroud)

如果我为map1添加一个类型签名,这一切都很好.

map1 :: Eq a => (a -> b) -> [a] -> [b]
Run Code Online (Sandbox Code Playgroud)

前两个函数对我来说几乎是一样的,所以我想我的问题只是"这里发生了什么?"

dfl*_*str 12

你受到单态限制困扰.写入的任何内容foo = ...- 意味着定义没有参数,并且没有给出显式类型 - 必须根据此限制具有非泛型类型.在这种情况下,泛型类型会像你说的,有要Eq a => (a -> b) -> [a] -> [b]的,但由于单态限制适用,既ab被取代(),可以推断可用的类型变量的最简单的类型.


Dan*_*her 6

但是,如果你使用无约束null而不是(== []),

Prelude> let map0 = \f -> \x -> if null (tail x) then [f (head x)] else f (head x) : map0 f (tail x)
Prelude> :t map0
map0 :: (a -> t) -> [a] -> [t]
Prelude> map (*2) [1 .. 10]
[2,4,6,8,10,12,14,16,18,20]
Run Code Online (Sandbox Code Playgroud)

它没有参数或签名.只有约束类型变量才受单态约束的约束.

如果你把定义map1放到一个文件中并尝试编译它或加载到ghci中,

Ambiguous type variable `a0' in the constraint:
  (Eq a0) arising from a use of `=='
Possible cause: the monomorphism restriction applied to the following:
  map1 :: forall t. (a0 -> t) -> [a0] -> [t] (bound at Maps.hs:3:1)
Probable fix: give these definition(s) an explicit type signature
              or use -XNoMonomorphismRestriction
In the expression: (tail x) == []
In the expression:
  if (tail x) == [] then
      [f (head x)]
  else
      f (head x) : (map1 f (tail x))
In the expression:
  \ x
    -> if (tail x) == [] then
           [f (head x)]
       else
           f (head x) : (map1 f (tail x))
Run Code Online (Sandbox Code Playgroud)

ghci只是以它所使用的方式抱怨ExtendedDefaultRules,否则你会得到一个可以理解的错误信息.