我想要一个+++添加两个数学向量的函数.
我可以实现向量[x, y, z]并使用:
(+++) :: (Num a) => [a] -> [a] -> [a]
(+++) = zipWith (+)
Run Code Online (Sandbox Code Playgroud)
因此适应任何n维向量(所以这也适用[x, y]).
或者我可以实现向量(x, y, z)并使用:
type Triple a = (a, a, a)
merge :: (a -> b -> c) -> Triple a -> Triple b -> Triple c
merge f (a, b, c) (x, y, z) = (f a x, f b y, f c z)
(+++) :: (Num a) => Triple …Run Code Online (Sandbox Code Playgroud) data Ray = Ray Vector Vector
Run Code Online (Sandbox Code Playgroud)
要么
type Ray = (Vector, Vector)
Run Code Online (Sandbox Code Playgroud)
哪个是惯用的哈希尔?我为什么要使用一个而不是另一个?
我不关心表现.
它似乎与功能没什么区别,例如:
trace :: Ray -> …
trace (Ray x d) = …
-- OR
trace (x, d) = …
Run Code Online (Sandbox Code Playgroud) 我喜欢这样一个事实:Go并没有给我百万种方法来做简单的事情 - 借用Python的Zen,"应该有一个 - 最好只有一个 - 显而易见的方法."
但是,我不清楚实例化类型的首选/惯用方法.基本类型很简单:
n := 0
t := 1.5
str := "Hello"
Run Code Online (Sandbox Code Playgroud)
但是结构呢?以下是等效的,如果是,哪个是首选的,为什么?
var f Foo
f := Foo{}
Run Code Online (Sandbox Code Playgroud)
切片怎么样?我可以做var xs []int,xs := []int{}或者xs := make([]int),但我认为第一种选择(与结构相对)与其他选项不同?我认为这也适用于地图.
有了指针,我听说new应该避免.这是一个很好的建议,如果是的话,什么才算是有效的用法new?
我意识到这可能部分是风格问题,但在任何情况下,选择特定风格的理由都会有所帮助.
如果我有一个java类,它是package-private(用"class"声明,而不是"public class"),如果里面的方法被声明为public或protected或package-private,那么确实没有区别,对吧?那么我应该使用哪种,或者何时应该使用哪种?我有点困惑.
要重复一个方法调用(或消息发送,我猜适当的术语是)每x秒,是否更好地使用NSTimer(NSTimer的scheduledTimerWithTimeInterval:target:selector:userInfo:repeats :)或让该方法以递归方式调用自身结束(使用performSelector:withObject:afterDelay)?后者不使用对象,但可能不太清晰/可读?另外,为了让您了解我正在做什么,它只是一个带有标签的视图,倒计时到午夜12点,当它变为0时,它会闪烁时间(00:00:00)并永远发出哔哔声.
谢谢.
编辑:同样,重复播放SystemSoundID(永远)的最佳方法是什么?编辑:我最终使用它来永远播放SystemSoundID:
// Utilities.h
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioServices.h>
static void soundCompleted(SystemSoundID soundID, void *myself);
@interface Utilities : NSObject {
}
+ (SystemSoundID)createSystemSoundIDFromFile:(NSString *)fileName ofType:(NSString *)type;
+ (void)playAndRepeatSystemSoundID:(SystemSoundID)soundID;
+ (void)stopPlayingAndDisposeSystemSoundID;
@end
// Utilities.m
#import "Utilities.h"
static BOOL play;
static void soundCompleted(SystemSoundID soundID, void *interval) {
if(play) {
[NSThread sleepForTimeInterval:(NSTimeInterval)interval];
AudioServicesPlaySystemSound(soundID);
} else {
AudioServicesRemoveSystemSoundCompletion(soundID);
AudioServicesDisposeSystemSoundID(soundID);
}
}
@implementation Utilities
+ (SystemSoundID)createSystemSoundIDFromFile:(NSString *)fileName ofType:(NSString *)type {
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:type];
SystemSoundID soundID;
NSURL *filePath = …Run Code Online (Sandbox Code Playgroud) 我对Putmonad提供的Builder直接使用内容感到困惑Data.Binary.我阅读了处理二进制数据的二进制生成部分,它似乎假设您应该使用Put,但它很短并不能解释原因.
Data.Binary.Put
Put monad.一个有效构造惰性字节串的monad.
Run Code Online (Sandbox Code Playgroud)type Put = PutM ()只需将Builder升级为Writer monad,应用于().
Data.Binary.Builder
高效构造惰性字节串.
什么是点Writer单子应用()?
我可以看到它Put是(一个类型的同义词)monad而Builder不是,但我真的不明白为什么Put需要.
在我的例子中,我正在渲染3D场景并将每个像素写为3个字节,然后将PPM格式的标题添加到开头(之后将使用PNG).
Binary似乎它是为了可以对二进制数据进行序列化和反序列化的类型进行实例化.这不完全是我正在做的事情,但是Binary为我的颜色类型实例化感觉很自然
instance (Binary a) => Binary (Colour a) where
put (Colour r g b) = put r >> put g >> put b
get = Colour <$> get <*> get <*> get
Run Code Online (Sandbox Code Playgroud)
这可以很容易地put一Colour Word8到24位.但是接下来我还要抓住标题,我不知道该怎么做.
是Builder隐藏在幕后,还是依赖于它?是 …
char *buf = malloc(bufsize)
char *ptr = buf;
…
while(condition) {
ptrdiff_t offset = ptr - buf; // <========== THIS LINE
// offset will never be negative because we only ever *increase* ptr
if ((size_t)offset > bufsize) {
// we need more room
bufsize += 128;
buf = realloc(buf, bufsize);
ptr = buf + offset; // buf might be in a completely new location
}
*ptr++ = … // write this byte
}
Run Code Online (Sandbox Code Playgroud)
这是有效还是未定义?
我会认为它是有效的,但我读到了一些关于它未定义的东西,所以我用谷歌搜索它.这些链接似乎不可避免地声称它未定义:
似乎每个人都推荐virtualenv用于多个python版本(在osx上),但它是否适用于python 3.0?我下载了它,它似乎没有...而且我真的不明白它是如何工作的,你能一次打开env吗?我想要的是离开系统python 2.5(显然),并让python 3.1.1与subversion pygame编写我自己的东西,和python 2.6与正常的稳定pygame用来运行其他的东西,如从pygame下载的pygame游戏.ORG.有关如何实现这一目标的任何帮助?谢谢.
好吧,我意识到virtualenv不是我想要的.
我Vector在Haskell 写了一个数学模块.
所以我开始:
data Vector a = Vector !a !a !a deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)
很好 - 这让我可以使用我想要的任何数值数据类型.问题是,我不希望被编写Double并Vector Double针对我不应该,原因很简单无处不在.所以我补充说:
type Scalar = Double
type Vector = Vector Scalar
Run Code Online (Sandbox Code Playgroud)
但当然第二行是错误的,因为现在有两个声明Vector.那么我该怎么改呢?我想,不,我将在我的代码中写这个,所以我想把类型别名简单地留下来Vector.这意味着我必须更改数据类型名称.但是,如果我改变了,那么我觉得我也应该改变构造函数,这会使一切更加混乱.但是如果让构造函数与类型别名具有相同的名称感觉很尴尬.
现在我有这个:
type Scalar = Double
type Vector = VectorT Scalar
data VectorT a = Vector !a !a !a deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)
我T随意挑选(我猜它代表"类型")但我不太确定这一点.通常,当我记录函数时,我会说-- Calculate the magnitude of a Vector,但VectorT我觉得我应该真的使用该类型名称.所以我只是将它们称为vectors(不是大写) - 除了我觉得我必须将此约定应用于每种数据类型的每个注释.
有没有人处于类似的情况?在这种情况下,谁能想到更优雅的解决方案?
haskell types naming-conventions algebraic-data-types type-alias