我对在Haskell中使用foldl的类型定义有疑问,我有类型:
data Client = GovOrg String
| Company String Integer Person String
| Individual Person Bool
deriving Show
data Person = Person String String Gender
deriving Show
data Gender = Male | Female | Unknown
deriving (Show, Eq, Ord)
data GenderStat = GenderStat Gender Integer deriving Show
使用以下函数定义foldl:
clientGender :: Client -> Gender
clientGender client = case client of
Company _ _ (Person _ _ gender) _ -> gender
Individual (Person _ _ gender) _ -> gender
_ -> Unknown
incrementGenderStat :: GenderStat -> GenderStat
incrementGenderStat (GenderStat gender num) = GenderStat gender (num + 1)
genderStats:: [GenderStat] -> Client -> [GenderStat]
genderStats [maleStat, femaleStat, unknownStat] client = case clientGender client of
Male -> [incrementGenderStat maleStat, femaleStat, unknownStat]
Female -> [maleStat, incrementGenderStat femaleStat, unknownStat]
Unknown -> [maleStat, femaleStat, incrementGenderStat unknownStat]
-- genderStatsOfClients :: Client a ->
genderStatsOfClients = foldl genderStats [GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0]
当我尝试将模块加载到ghci
时,它会抛出错误:
• Ambiguous type variable ‘t0’ arising from a use of ‘foldl’ │
prevents the constraint ‘(Foldable t0)’ from being solved. │
Relevant bindings include │
genderStatsOfClients :: t0 Client -> [GenderStat] │
(bound at src/Section2/DataTypes.hs:82:1) │
Probable fix: use a type annotation to specify what ‘t0’ should be. │
These potential instances exist: │
instance Foldable (Either a) -- Defined in ‘Data.Foldable’ │
instance Foldable Maybe -- Defined in ‘Data.Foldable’ │
instance Foldable ((,) a) -- Defined in ‘Data.Foldable’ │
...plus one other │
...plus 22 instances involving out-of-scope types │
(use -fprint-potential-instances to see them all) │
• In the expression: │
foldl │
genderStats │
[GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0] │
In an equation for ‘genderStatsOfClients’: │
genderStatsOfClients │
= foldl │
genderStats │
[GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0] │
Failed, modules loaded: none.
我试图通过为建议的函数提供类型注释来解决这个问题:
-- genderStatsOfClients :: Foldable Client => ([GenderStat] -> a -> [GenderStat]) -> [GenderStat] -> [a] -> [GenderStat]
我想知道如何在这里提供适当的类型约束,如果我使用Foldable Client a
,它说它期望Foldable
减少一个参数。
我也尝试了类型定义:
genderStatsOfClients :: (Foldable f, Client a) => ([GenderStat] -> (f a) -> [GenderStat]) -> [GenderStat] -> [(f a)] -> [GenderStat]
genderStatsOfClients = foldl genderStats [GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0]
抛出错误:
src/Section2/DataTypes.hs:81:38: error: │
• Expecting one fewer argument to ‘Client’ │
Expected kind ‘* -> Constraint’, but ‘Client’ has kind ‘*’ │
• In the type signature: │
genderStatsOfClients :: (Foldable f, Client a) => │
([GenderStat] -> (f a) -> [GenderStat]) │
-> [GenderStat] -> [(f a)] -> [GenderStat]
答案 0 :(得分:3)
注释你#import "MovieView.h"
#import <AudioToolbox/AudioToolbox.h>
@implementation MovieView
@synthesize selectedCountry, vImagePreview, playit;
- (void)viewDidLoad {
[super viewDidLoad];
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MMM d hh:mm:ss a"];
// display in 12HR/24HR (i.e. 11:25PM or 23:25) format according to User Settings
NSString *currentTime = [dateFormatter stringFromDate:today];
self.navigationController.navigationBarHidden = YES;
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
NSError* error4 = nil;
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryAmbient error:&error4];
OSStatus propertySetError = 0;
UInt32 allowMixing = true;
propertySetError |= AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(allowMixing), &allowMixing);
// Activate the audio session
error4 = nil;
if (![audioSession setActive:YES error:&error4]) {
NSLog(@"AVAudioSession setActive:YES failed: %@", [error4 localizedDescription]);
}
//tests
// Set audio session category to "play and record"
//endtests
//this is the end of recording the video and audio
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *proud = [[documentsDirectoryPath stringByAppendingPathComponent:@"proud"] stringByAppendingPathComponent:selectedCountry];
NSURL *movieURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"BlueHarvest" ofType:@"mp4"]];
player =
[[MPMoviePlayerController alloc] initWithContentURL: movieURL];
player.useApplicationAudioSession=YES;
[player prepareToPlay];
player.controlStyle = MPMovieControlStyleNone;
player.allowsAirPlay = NO;
player.scalingMode = MPMovieScalingModeFill;
player.view.frame = self.view.frame;
[self.view insertSubview:player.view belowSubview:vImagePreview];
[player setFullscreen:YES animated:YES];
// ...
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitedFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(moviePlayerWillExitFullscreen:)
name:MPMoviePlayerWillExitFullscreenNotification
object:player];
[player play];
session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
session.sessionPreset = AVCaptureSessionPresetMedium;
CALayer *viewLayer = self.vImagePreview.layer;
NSLog(@"viewLayer = %@", viewLayer);
self.captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
self.captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.captureVideoPreviewLayer.frame = self.vImagePreview.bounds;
[self.captureVideoPreviewLayer setCornerRadius:14];
[self.captureVideoPreviewLayer setBorderWidth:3.0];
[self.captureVideoPreviewLayer setBorderColor:[[UIColor whiteColor] CGColor]];
self.captureVideoPreviewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
[[vImagePreview layer] setCornerRadius:14];
[[vImagePreview layer] setBorderWidth:3.0];
[[vImagePreview layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[self.vImagePreview.layer addSublayer:self.captureVideoPreviewLayer];
AVCaptureDevice *device = [self frontFacingCameraIfAvailable];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
NSLog(@"ERROR: trying to open camera: %@", error);
}
AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *error2 = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error2];
AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
NSString *archives = [documentsDirectoryPath stringByAppendingPathComponent:@"archives"];
NSString *editedfilename = [[selectedCountry lastPathComponent] stringByDeletingPathExtension];
NSString *datestring = [[editedfilename stringByAppendingString:@" "] stringByAppendingString:currentTime];
NSLog(@"%@", datestring);
NSString *outputpathofmovie = [[archives stringByAppendingPathComponent:datestring] stringByAppendingString:@".mp4"];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputpathofmovie];
[session addInput:input];
[session addInput:audioInput];
[session addOutput:movieFileOutput];
AVCaptureConnection *videoConnection = nil;
for ( AVCaptureConnection *connection in [movieFileOutput connections] )
{
NSLog(@"%@", connection);
for ( AVCaptureInputPort *port in [connection inputPorts] )
{
NSLog(@"%@", port);
if ( [[port mediaType] isEqual:AVMediaTypeVideo] )
{
videoConnection = connection;
}
}
}
if([videoConnection isVideoOrientationSupported]) // **Here it is, its always false**
{
[videoConnection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
}
[session commitConfiguration];
[session startRunning];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
NSLog(@"OutputURL%@", outputURL);
}
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
switch (orientation) {
case UIInterfaceOrientationPortrait:
[self.captureVideoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortrait];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[self.captureVideoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationPortraitUpsideDown];
break;
case UIInterfaceOrientationLandscapeLeft:
[self.captureVideoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeLeft];
break;
case UIInterfaceOrientationLandscapeRight:
[self.captureVideoPreviewLayer.connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
break;
}
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error {
//finished
NSLog(@"ErrorMessage%@", error);
}
-(IBAction)endcall {
[player stop];
[session stopRunning];
}
-(AVCaptureDevice *)frontFacingCameraIfAvailable
{
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *captureDevice = nil;
for (AVCaptureDevice *device in videoDevices)
{
if (device.position == AVCaptureDevicePositionFront)
{
captureDevice = device;
break;
}
}
// couldn't find one on the front, so just get the default video device.
if ( ! captureDevice)
{
captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}
return captureDevice;
}
- (void) movieFinishedCallback:(NSNotification*) aNotification {
NSLog(@"MovieDone");
[player stop];
[player.view removeFromSuperview];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
[session stopRunning];
[self.navigationController popToRootViewControllerAnimated:NO];
}
- (void) exitedFullscreen:(NSNotification*) aNotification {
NSLog(@"MovieDone");
[player.view removeFromSuperview];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerDidExitFullscreenNotification
object:player];
}
- (void)moviePlayerWillExitFullscreen:(NSNotification*) aNotification {
[player stop];
[session stopRunning];
[self dismissMoviePlayerViewControllerAnimated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerWillExitFullscreenNotification object:player];
}
@end
的定义,告诉编译器你的可折叠是一个列表:
genderStatsOfClients