我需要什么类型的签名才能将函数列表转换为haskell代码?

3 haskell

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

我做了一个名为haskell的函数funlist.它的作用是获取起始值和函数列表,并将列表中的所有函数应用于起始值.

funlist thing [function] = function thing
funlist thing (function:functions) = funlist (function thing) functions
funlist _ _ = error "need a list of functions"
Run Code Online (Sandbox Code Playgroud)

这个函数的问题在于它有一种类型funlist :: t -> [t -> t] -> t.该类型意味着虽然ghc将允许不将起始值转换为完全不同类型的函数列表(例如[sin,cos,tan]将被允许​​),但是将起始值转换为不同类型(例如show)的函数将生成错误因为该功能与类型签名不匹配.

这不是该功能应该如何工作.它应该能够获取更改起始值类型的函数列表(例如[sin,show]).这个函数基本上转换funlist 5 [sin,cos,tan,isInfinite,show]show $ isInfinite $ tan $ cos $ sin $ 5,而后者工作,前者则不然.

有什么办法可以让这个功能正常工作吗?

编辑:我知道.>>>,我只是想知道,如果有一种方法,使这项工作.

Chr*_*icz 7

你可以用GADT写下你想要的东西:

{-# LANGUAGE GADTs #-}
module Funlist where

data F x y where
  Id :: F a a
  Ap :: (a->b) -> F b c -> F a c

-- A very round about way to write f x = x + x

f1 :: Int -> Char
f1 = toEnum

f2 :: Char -> String
f2 x = x:x:[]

f3 :: String -> [Int]
f3 = map fromEnum

f4 :: [Int] -> Integer
f4 = foldr (+) 0 . map toInteger

f_list :: F Int Integer
f_list = Ap f1 (Ap f2 (Ap f3 (Ap f4 Id)))

ap :: F a b -> a -> b
ap Id x = x
ap (Ap f gs) x = ap gs (f x)
Run Code Online (Sandbox Code Playgroud)

现在ap f_list 65130

  • 这是 - 这里所说的自反,传递闭包施工(克林星)(>)实例http://stackoverflow.com/questions/10777283/type-threaded-heterogenous-lists-and-defaulting-with-type-families/10777626#10777626 (3认同)

dfl*_*str 6

这不适用于Haskell中的普通函数/普通列表,因为它需要动态类型语言,而不是像Haskell那样的静态类型语言.该funlist功能不能有不同的类型取决于哪些功能列表的内容是在运行时; 它的类型必须在编译时知道.此外,编译器必须能够检查函数链是否有效,因此您不能使用该列表[tan, show, sin]作为示例.

这个问题有两种解决方案.

您可以使用异类列表.这些列表可以存储每个元素是不同类型的列表.然后,您可以检查每个元素必须是函数的约束,并且一个元素返回类型必须是下一个函数的参数类型.这很快就会变得非常困难.

您还可以使用Data.Dynamic函数来获取和返回动态类型.在这种情况下,您必须执行一些动态类型转换.


dav*_*420 6

如果要对这个函数列表进行操作,则将它们应用于管道中的单个值,然后执行以下操作,而不是编写和调用funlist函数:

show . isInfinite . tan . cos . sin $ 5
Run Code Online (Sandbox Code Playgroud)

或者,如果您不希望代码中的列表颠倒,请执行以下操作:

import Control.Arrow (>>>)

(sin >>> cos >>> tan >>> isInfinite >>> show) 5
Run Code Online (Sandbox Code Playgroud)