我正在考虑这样的功能:
> let applyN (initial : 't) (n:int) (f : 't -> 't) = seq {1..n} |> Seq.fold (fun s _ -> f s) initial;;
val applyN : initial:'t -> n:int -> f:('t -> 't) -> 't
> applyN 0 10 (fun x -> x + 1);;
val it : int = 10
注意:代码是F#但是我用haskell,ocaml和ml标签标记了问题,因为如果函数不存在于F#库中但是它存在于其他语言中我想使用相同的名称
答案 0 :(得分:7)
你会得到(非常接近)答案,例如使用Hayoo(或Hoogle,但Hoogle不灵活 - iterateN
未找到):
搜索Int -> (a -> a) -> a -> a
会显示多个功能可以执行您想要但不属于stdlib的功能。
搜索applyN
返回的函数与您正在查找的类型签名完全相同。
通过搜索Int -> (a -> a) -> a
laxing返回值(注意最后丢失的-> a
),得到erdeszt已经提到的iterateN :: Int -> (a -> a) -> a -> Seq a
函数。< / p>
P.S。 Hoogle似乎更有能力翻转参数顺序:(a -> a) -> Int -> a -> Seq a
成功返回&#39; iterateN :: Int - &gt; (a - &gt; a) - &gt; a - &gt; Seq a`,Hayoo没有。
答案 1 :(得分:3)
Data.Sequence模块中的Haskell有一个iterateN函数,看起来就像你要查找的那个。
它实际上只是一个迭代+结合的组合:
@using Orchard.Blogs.Models
@using Orchard.MediaLibrary.Fields
@using Orchard.Users.Models
@using Orchard.Utility.Extensions
@{
// Standard Orchard stuff here...
if ( Model.Title != null )
{
Layout.Title = Model.Title;
}
Model.Classes.Add("content-item");
var contentTypeClassName = ( (string)Model.ContentItem.ContentType ).HtmlClassify();
Model.Classes.Add(contentTypeClassName);
var tag = Tag(Model, "article");
// And here we go:
// Get the blogPost
var blogPostPart = (BlogPostPart)Model.ContentItem.BlogPostPart;
// Either access the creator directly
var blogPostAuthor = blogPostPart.Creator;
// Or go this way
var blogPostAuthorAsUserPart = ( (dynamic)blogPostPart.ContentItem ).UserPart as UserPart;
// Access your UserExtensions part
var userExtensions = ( (dynamic)blogPostAuthor.ContentItem ).UserExtensions;
// profit
var profilePicture = (MediaLibraryPickerField)userExtensions.ProfilePicture;
}
@tag.StartElement
<header>
@Display(Model.Header)
@if ( Model.Meta != null )
{
<div class="metadata">
@Display(Model.Meta)
</div>
}
<div class="author">
<img src="@profilePicture.FirstMediaUrl"/>
</div>
</header>
@Display(Model.Content)
@if ( Model.Footer != null )
{
<footer>
@Display(Model.Footer)
</footer>
}
@tag.EndElement
这是f#版本的迭代(from here),Seq.take是F#标准库的一部分:
let iterateN n f x = take n (iterate f x)
答案 2 :(得分:1)
可能的解决方案:
> import Data.Monoid
> import Debug.SimpleReflect -- not really needed, just for showing the result
> (appEndo . mconcat . replicate 5 . Endo $ f) a
f (f (f (f (f a))))
另一个(已经提到过):
> iterate f a !! 5
f (f (f (f (f a))))
(如果你想把它变成一个函数,添加lambdas)
然而,不要忘记Haskell是懒惰的:上述方法将首先应用f
多次构建一个thunk,然后才开始评估。有时f
可以在恒定的空间中迭代,例如当f :: Int -> Int
(和f
本身在恒定空间中工作时),但上述方法仅适用于线性空间。
我将通过自己的严格迭代组合来定义,例如:
iter :: Int -> (a -> a) -> a -> a
iter 0 _ x = x
iter n f x = iter (pred n) f $! f x
甚至,
iter n f x = foldl' (flip $ const f) x [1..n]
这更像是问题中已经发布的Haskell翻译。
或者,我们可以定义iterate
的严格版本(恕我直言应该已经存在......)
iterate' :: (a -> a) -> a -> [a]
iterate' f x = x : (iterate' f $! f x)
答案 3 :(得分:0)
要添加其他方法列表,
import Control.Monad.State.Lazy
applyN initial n =
flip execState initial . replicateM_ n . modify