Haskell:创建一个在列表上行动的功能

use*_*846 1 haskell higher-order-functions

可能重复:
为什么haskell中不允许这样的函数定义?

我想创建一个函数flist,它接受一个函数f作为参数,并返回另一个函数,其参数将是一个列表,但行为完全相同f.

例如:

let f x1 x2 x3 = x1+ x2 + x3
Run Code Online (Sandbox Code Playgroud)

我想要这种行为

(flist f) [x1,x2,x3] = x1+x2+x3
Run Code Online (Sandbox Code Playgroud)

当列表长度不是3时,它可能以任何方式表现.flist应该照顾任何函数(不仅是带有3个参数的函数,即if g x1 x2 x3 x4 = x1+x2+x3*x4,then (flist g) [x1,x2,x3,x4] = x1+x2+x3*x4).

我试过这个,

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

但它没有用.我该如何实现这一目标?我可以使用数据类型来执行此操作吗?

Ste*_*ans 5

对于类型家庭,你可以走得很远 - 但它肯定不适合胆小的人:

{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies      #-}

class FList a where
  type Point a
  flist :: a -> [Point a] -> Point a

instance FList (a -> a) where
  type Point (a -> a) = a
  flist f [x] = f x

instance (FList (a -> b), a ~ Point (a -> b)) => FList (a -> (a -> b)) where
  type Point (a -> (a -> b)) = Point (a -> b)
  flist f (x : xs) = flist (f x) xs
Run Code Online (Sandbox Code Playgroud)

以您为例,我们得到:

> let f x y z = x + y + z
> flist f [2, 3, 5]
10
Run Code Online (Sandbox Code Playgroud)