小编Guy*_*der的帖子

为什么"代码不够通用"?

任何人都可以解释为什么下面的第二个例子不会编译?

'测试2'给出了"错误FS0670:这个代码不够通用.类型变量^ a不能一概而论,因为它会逃避它的范围." 我无法理解此错误消息.

// Test 1
type test1<'a> = | A of 'a 
  with
    override t.ToString() = 
      match t with
      | A a -> a.ToString()

// Test 2
type test2<'a> = | A of 'a 
  with
    override t.ToString() = 
      match t with
      | A a -> string a

// Test 3
type test3<'a> = | A of 'a 
  with
    override t.ToString() = 
      match t with
      | A a -> string (a :> obj)
Run Code Online (Sandbox Code Playgroud)

generics f# type-inference inline

12
推荐指数
1
解决办法
1424
查看次数

Haskell数据类型使用良好的实践

阅读"真实世界Haskell"我发现了一些有关数据类型的有趣问题:

这种模式匹配和位置数据访问使得它看起来像数据和在其上运行的代码之间具有非常紧密的耦合(尝试向Book添加内容,或者更糟糕地更改现有部件的类型).

在命令式(特别是OO)语言中,这通常是一件非常糟糕的事情......它在Haskell中不被视为一个问题吗? 来自RWH的评论

实际上,编写一些Haskell程序时,我发现当我对数据类型结构进行小的更改时,它几乎影响了使用该数据类型的所有函数.也许有一些数据类型使用的良好实践.如何最小化代码耦合?

haskell algebraic-data-types

12
推荐指数
3
解决办法
994
查看次数

标准ML是否支持Unicode?

标准ML是否支持Unicode?

我相信它没有,但找不到任何SML说明这样的权威文档.

是或否是所有需要,但你必须知道一个事实.没有猜测或我相信答案.权威链接会更好.

sml polyml

12
推荐指数
1
解决办法
992
查看次数

额外的蜥蜴和尾巴的目的是什么.在F#实现与C#?

以下C#函数:

T ResultOfFunc<T>(Func<T> f)
{
    return f();
}
Run Code Online (Sandbox Code Playgroud)

毫不奇怪地汇编到这个:

IL_0000:  ldarg.1     
IL_0001:  callvirt    05 00 00 0A 
IL_0006:  ret  
Run Code Online (Sandbox Code Playgroud)

但是等效的F#功能:

let resultOfFunc func = func()
Run Code Online (Sandbox Code Playgroud)

汇编到这个:

IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  ldnull      
IL_0003:  tail.       
IL_0005:  callvirt    04 00 00 0A 
IL_000A:  ret 
Run Code Online (Sandbox Code Playgroud)

(两者都处于发布模式).开头有一个额外的小窍门,我并不太好奇,但有趣的是附加ldnulltail.说明.

我的猜测(可能是错误的)是ldnull必要的,如果函数是void这样,它仍然返回something(unit),但这并不能解释tail.指令的目的是什么.如果函数确实在栈上推送了某些东西会发生什么呢?是不是它会被一个不会弹出的额外null所困?

c# f# cil tail-recursion tail-call-optimization

12
推荐指数
1
解决办法
211
查看次数

避免F#中的代码重复

我有两个代码片段,试图将浮动列表转换为Vector3或Vector2列表.这个想法是从列表中一次取2/3个元素并将它们组合成一个向量.最终结果是一系列向量.

    let rec vec3Seq floatList =
        seq {
            match floatList with
            | x::y::z::tail -> yield Vector3(x,y,z)
                               yield! vec3Seq tail
            | [] -> ()
            | _ -> failwith "float array not multiple of 3?"
            }

    let rec vec2Seq floatList =
        seq {
            match floatList with
            | x::y::tail -> yield Vector2(x,y)
                            yield! vec2Seq tail
            | [] -> ()
            | _ -> failwith "float array not multiple of 2?"
            }
Run Code Online (Sandbox Code Playgroud)

代码看起来很相似,但似乎无法提取公共部分.有任何想法吗?

f# tail-recursion code-duplication

11
推荐指数
1
解决办法
376
查看次数

在Haskell中,为什么我需要在我的阻止之前放一个$?

[这个问题是由"真实世界Haskell"中的第9章推动的]

这是一个简单的功能(减少到必需品):

saferOpenFile path = handle (\_ -> return Nothing) $ do
      h <- openFile path ReadMode
      return (Just h)
Run Code Online (Sandbox Code Playgroud)

我为什么需要那个$

如果要处理的第二个参数不是do块,我不需要它.以下工作正常:

handle (\_ -> putStrLn "Error calculating result") (print x)
Run Code Online (Sandbox Code Playgroud)

当我尝试删除$编译失败.如果我明确添加parens,我可以让它工作,即

saferOpenFile path = handle (\_ -> return Nothing)  (do
      h <- openFile path ReadMode
      return (Just h))
Run Code Online (Sandbox Code Playgroud)

我可以理解这一点,但我想我希望当Haskell击中do它时应该想到"我正在开始阻止",我们不应该明确地把它放在$那里来解决问题.

我还想过将do块推到下一行,如下所示:

saferOpenFile path = handle (\_ -> return Nothing)  
  do
    h <- openFile path ReadMode
    return (Just h)
Run Code Online (Sandbox Code Playgroud)

但是如果没有parens也行不通.这让我感到困惑,因为以下工作:

add a b …
Run Code Online (Sandbox Code Playgroud)

haskell

11
推荐指数
3
解决办法
583
查看次数

F#尾调用优化2个递归调用?

当我写这个函数时,我知道我不会得到尾调优化.我仍然没有想出一个处理这个的好方法,并希望别人可以提供建议.

我有一棵树:

type Heap<'a> =
| E
| T of int * 'a * Heap<'a> * Heap<'a> 
Run Code Online (Sandbox Code Playgroud)

我想要计算其中有多少个节点:

let count h =
    let rec count' h acc =
        match h with 
        | E -> 0 + acc
        | T(_, value, leftChild, rightChild) ->
            let acc = 1 + acc
            (count' leftChild acc) + (count' rightChild acc)

    count' h 0
Run Code Online (Sandbox Code Playgroud)

由于添加了子节点的计数,因此未进行优化.如果树有100万个节点,任何想法如何制作这样的东西?

谢谢,德里克


这是使用CPS实现计数.它仍然吹响了堆栈.

let count h =
    let rec count' h acc cont =
        match h with
        | E -> cont …
Run Code Online (Sandbox Code Playgroud)

recursion f# functional-programming tail-recursion tail-call-optimization

11
推荐指数
2
解决办法
1108
查看次数

如何从ajaxStart函数获取请求的URL?

我可以从中获取请求的URL ajaxStart吗?我想为所有ajax请求执行一个公共操作,接受一些请求.

jquery

11
推荐指数
2
解决办法
9476
查看次数

在Haskell中流式传输目录的递归下降

我正在尝试使用Haskell进行目录结构的递归下降.我想只根据需要检索子目录和文件(懒惰).

我编写了以下代码,但是当我运行它时,跟踪显示在第一个文件之前访问了所有目录:

module Main where

import Control.Monad ( forM, forM_, liftM )
import Debug.Trace ( trace )
import System.Directory ( doesDirectoryExist, getDirectoryContents )
import System.Environment ( getArgs )
import System.FilePath ( (</>) )

-- From Real World Haskell, p. 214
getRecursiveContents :: FilePath -> IO [FilePath]
getRecursiveContents topPath = do
  names <- getDirectoryContents topPath
  let
    properNames =
      filter (`notElem` [".", ".."]) $
      trace ("Processing " ++ topPath) names
  paths <- forM properNames $ \name -> do
    let path = topPath …
Run Code Online (Sandbox Code Playgroud)

haskell directory-structure lazy-evaluation

11
推荐指数
2
解决办法
1938
查看次数

F#异步递归调用中的内存泄漏

我很困惑为什么这个功能显示内存不断增加

let rec startRead1() = 
  async {
    do! Async.Sleep 1
    System.GC.Collect()
    let mem = System.GC.GetTotalMemory(true)
    printfn "%d" mem
    do! startRead1()
  }
Run Code Online (Sandbox Code Playgroud)

25676 36760 36840 36884 36928 36972 37016 37060 37104 37328 37362 37212 37456 37500 37544 37588 37632 37676 37720 37764 37808 37852 37896 37940 37984 38028 38072 38116 38160 38204 38248 38292 38336 38380 38424 38468 38512 38556 38600 38644 38688 38732 38776 38820 38864 38908 38952 38996 39040 39084 39128 39172 39216 ^ C按任意键继续...

[<EntryPoint>]
let main _ …
Run Code Online (Sandbox Code Playgroud)

f# memory-leaks asynchronous tail-recursion

11
推荐指数
1
解决办法
738
查看次数